package com.syni.mdd.yhd.common.all.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.qcloud.Module.Vod;
import com.qcloud.QcloudApiModuleCenter;
import com.syni.mdd.sjb.common.component.utils.common.utils.AppConfig;
import com.syni.mdd.sjb.common.component.utils.common.utils.BeanUtils;
import com.syni.mdd.sjb.common.component.utils.common.utils.ParamsMap;
import com.syni.mdd.sjb.common.component.utils.common.utils.ResultMapHelper;
import com.syni.mdd.yhd.common.all.constants.Constants;
import com.syni.mdd.yhd.common.all.constants.ResultCode;
import com.syni.mdd.yhd.common.all.constants.ResultMsg;
import com.syni.mdd.yhd.common.all.dao.jpa.BmsVideoDao;
import com.syni.mdd.yhd.common.all.dao.jpa.BmsVideoInsertDao;
import com.syni.mdd.yhd.common.all.dto.requestDto.video.BmsVideoReDto;
import com.syni.mdd.yhd.common.all.entity.*;
import com.syni.mdd.yhd.common.all.entity.user.BmsUser;
import com.syni.mdd.yhd.common.all.entity.video.BmsVideoInsertDto;
import com.syni.mdd.yhd.common.all.listen.video.VideoEvent;
import com.syni.mdd.yhd.common.all.service.impl.BaseService;
import com.syni.mdd.yhd.common.all.utils.*;
import lombok.extern.log4j.Log4j2;
import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
@Log4j2
public class BmsVideoService extends BaseService<BmsVideo, Integer> {



    @Value("${range.distance}")
    private String rangeDistance;

    @Value("${redis.max.video.num}")
    private Integer redisMaxVideoNum;

    @Value("${once.video.num}")
    private Integer onceVideoNum;

    @Value("${min.video.num}")
    private Integer minVideoNum;

    @Value("${app.search.video.total:100}")
    private Integer searchVideoTotal;

    @Value("${app.debug:1}")
    private Integer isDebug;

    //默认推荐等级
    final static String ALevel = "A";

    final static String BLevel = "B";

    final static String Elevel = "E";

    final static String CLevel = "C";

    final static String DLevel = "D";

    final static String xiangZhouDistinct = "香洲区";

    final static String douMenDistinct = "斗门区";

    final static String jinWanDistinct = "金湾区";

    final static String defaultRecommend = BLevel;

    //游客前缀id
    public final static String visitorPrfix = "X999";
    public final static Integer isDelete = Constants.COMMON_FLAG_FALSE_INT;
    public final static Integer isRelease = Constants.COMMON_FLAG_FALSE_INT;
    public final static Integer isOff = Constants.COMMON_FLAG_FALSE_INT;
    private final Integer userLikeFoot = 1;

    //视频点赞
    public final static String videoLike = "like";
    //商家打卡
    public final static String businessDk = "dk";
    //视频评论
    public final static String videoComment = "comment";

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    BmsVideoDao bmsVideoDao;

    @Autowired
    BmsVideoInsertDao bmsVideoInsertDao;

    @Autowired
    BmsBusinessService bmsBusinessService;

    @Autowired
    BmsUserVideoLikeService bmsUserVideoLikeService;

    @Autowired
    BmsUserVideoDkService bmsUserVideoDkService;

    @Autowired
    BmsSearchLogService bmsSearchLogService;

    @Autowired
    BmsDxCommentService bmsDxCommentService;

    @Autowired
    BmsUserVideoService bmsUserVideoService;

    @Autowired
    BmsDxClientRoleService bmsDxClientRoleService;

    @Autowired
    BmsBusinessLabelService bmsBusinessLabelService;

    @Autowired
    BmsUserBusinessAuthService bmsUserBusinessAuthService;

    @Autowired
    BmsDxNewsService bmsDxNewsService;

    @Autowired
    BmsDxCouponService bmsDxCouponService;

    @Autowired
    BmsDxGroupBuyService bmsDxGroupBuyService;

    @Autowired
    ApplicationContext applicationContext;

    @Autowired
    EntityManager entityManager;

    @Autowired
    BmsUserService bmsUserService;

    @Autowired
    BmsBusinessTypeService bmsBusinessTypeService;

    @Autowired
    BmsBusinessTypeRelationService bmsBusinessTypeRelationService;

    @Override
    public BmsVideoDao getBaseDao() {
        return bmsVideoDao;
    }

    public List<BmsVideo> getBmsVideoList(String userId,String latitude,
                                          String longitude,String addrCity,String addrDistrict){
        Integer[] ids = findBussessisNearby(latitude,longitude,addrCity,addrDistrict);
        Integer pageNum = 1;
        Integer pageSize = redisMaxVideoNum;
        Pageable pageable = PageRequest.of(pageNum - 1,pageSize,Sort.Direction.DESC,"likeTimes","newTime");
        List<BmsVideo> bmsVideos = new ArrayList<>();
        List<BmsVideo> bmsVideoList =  bmsVideoDao.findAll(new Specification<BmsVideo>() {
            @Override
            public Predicate toPredicate(Root<BmsVideo> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                Map<String,Object> searchMap = new HashMap<String,Object>(){{
                   put("isRelease",Constants.COMMON_FLAG_FALSE);
                    put("isDelete",Constants.COMMON_FLAG_FALSE);
                    put("ids",ids);
                }};
                criteriaQuery.where(structureSqlBuild(root,criteriaBuilder,searchMap));
                return null;
            }
        },pageable).getContent();
        bmsVideos.addAll(bmsVideoList);
        Integer videoNum = onceVideoNum;
        List<BmsVideo> resultBmsVideoList = new LinkedList<>();
        if(bmsVideos.size() > 0) {
            getListPostHand(bmsVideos,latitude,longitude,userId);
            if(videoNum > bmsVideos.size()){
                videoNum = bmsVideos.size();
            }
            List<BmsVideo> resultVideos = bmsVideos.subList(0,videoNum);
            resultBmsVideoList.addAll(resultVideos);
            bmsVideos.removeAll(resultVideos);
            /*for (int i = 0; i < videoNum; i++) {
                BmsVideo bmsVideo = bmsVideos.get(i);
                bmsVideos.remove(i);
                resultBmsVideoList.add(bmsVideo);
                //bmsVideos.offerLast(bmsVideo);
            }*/
        }
        //将队列存进redis
        addVideoToRedis(bmsVideos, String.format("user:%s", userId));
        return resultBmsVideoList;
    }

    public List<BmsVideo> getBmsVideoListSecond(String userId,String latitude,
                                          String longitude,String addrCity,String addrDistrict){
        List<BmsVideo> bmsVideos = new ArrayList<>();
        /*Map<String,Object> conditionMap = new ConcurrentHashMap<>();
        conditionMap.put("isDelete",0);
        conditionMap.put("isOff",0);
        conditionMap.put("isRelease",0);
        Map<String,Object> groupBuyMap = new HashMap<>();
        groupBuyMap.put("cloudFileId_GB",1);*/
        //conditionMap.put("cloudFileTranscodeDrnUrl_N",1);
        //Pageable pageable = BmsCommonService.getPageable(1,30, Sort.Direction.DESC,"newTime");
        //bmsVideos.addAll(bmsVideoDao.findAll(new SpecificationUtils(conditionMap,groupBuyMap),pageable).getContent());
        //bmsVideos.addAll(bmsVideoDao.findAll(new SpecificationUtils(conditionMap)));
        //boolean isOpenLocationn = false;
        if(StringUtils.isNotBlank(latitude) && StringUtils.isNotBlank(longitude)
                && StringUtils.isNotBlank(addrCity) && StringUtils.isNotBlank(addrDistrict)) {
            //寻找当前区所有的视频
            List<BmsVideo> cityVideo = this.getVideoIdsByByCityDistrict(addrCity,addrDistrict);
            Set<Integer> videoIds = cityVideo.stream().map(BmsVideo::getId).collect(Collectors.toSet());
            if(videoIds.size() > 0){
                //先找寻3公里内当前区的视频（包含所有等级）
                bmsVideos.addAll(findWithinThreeKilometersDistinct(0d,3000d,longitude,latitude,videoIds));
                //先找寻当前市，推过以外的视频id
                Set<Integer> videoIdsThanThreeKm = findThanThreeKmVideo(addrCity,addrDistrict,bmsVideos.stream().map(BmsVideo::getId).collect(Collectors.toSet()));
                //再找寻推过以外的视频的A推视频(由近及远)
                bmsVideos.addAll(findThanThreeKmVideoByLevel(latitude,longitude,addrDistrict,videoIdsThanThreeKm,
                        ALevel,BLevel,Elevel,CLevel,DLevel));
            }
            /*Map<String,List<BmsVideo>> videos =  this.getThreeKmVideo(latitude,longitude,cityVideo);
            bmsVideos.addAll(videos.get("threeKmVideo"));*/
            //isOpenLocationn = true;
            //当前区3公里内的videoId
            //Set<Integer> videoIds = findWithinThreeKilometersDistinct(0d,3d,longitude,latitude);
            //bmsVideos.addAll(findWithinThreeKilometersDistinct(0d,3000d,longitude,latitude));

            /*bmsVideos.addAll(getMoreThreeKmVideoByLevel(addrDistrict,videos.get("otherVideo")
                    ,ALevel,BLevel,CLevel,DLevel));*/
            //再找寻推过以外的B推视频(由近到远)
            //bmsVideos.addAll(findThanThreeKmVideoByLevel(latitude,longitude,addrDistrict,videoIdsThanThreeKm,BLevel));
            //再找寻推过以外的C推视频(由近到远)
            //bmsVideos.addAll(findThanThreeKmVideoByLevel(latitude,longitude,addrDistrict,videoIdsThanThreeKm,CLevel));
            //再找寻推过以外的D推视频(由近到远)
            //bmsVideos.addAll(findThanThreeKmVideoByLevel(latitude,longitude,addrDistrict,videoIdsThanThreeKm,DLevel));
        }else if(StringUtils.isNotBlank(addrCity) || StringUtils.isNotBlank(addrDistrict)){
            //未开启定位，但选择了区域
            //找出该区域所有的视频的ids
            Set<Integer> videoIds = getVideoIdsByByAddrCityAndAddrDistrict(addrCity,addrDistrict);
            List<BmsVideo> bmsVideoList = new LinkedList<>();
            if(videoIds.size() > 0){
                Sort sort = Sort.by(Sort.Direction.DESC,"likeTimes","newTime");
                bmsVideoList =  bmsVideoDao.findAll(new Specification<BmsVideo>() {
                    @Override
                    public Predicate toPredicate(Root<BmsVideo> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                        Map<String,Object> searchMap = new HashMap<String,Object>(){{
                            put("ids",videoIds);
                        }};
                        criteriaQuery.where(structureSqlBuild(root,criteriaBuilder,searchMap));
                        //加多一个强推
                        return null;
                    }
                },sort);
            }
            Map<String,List<BmsVideo>> bmsVideoMap = doVideoTypeByRecomment(bmsVideoList);
            bmsVideos.addAll(bmsVideoMap.get(ALevel));
            bmsVideos.addAll(bmsVideoMap.get(BLevel));
            bmsVideos.addAll(bmsVideoMap.get(Elevel));
            bmsVideos.addAll(bmsVideoMap.get(CLevel));
            bmsVideos.addAll(bmsVideoMap.get(DLevel));
        }else {
            //未开启定位，也有没有选择区域
            bmsVideos.addAll(findNoLocation());
        }
        Integer videoNum = onceVideoNum;
        List<BmsVideo> resultVideos = new LinkedList<>();
        if(bmsVideos.size() > 0) {
            getListPostForVideoList(bmsVideos,userId);
            calculatedDistance(bmsVideos, latitude, longitude);
            bmsVideos = postHandleVideoOrder(userId,bmsVideos);
            if(videoNum > bmsVideos.size()){
                videoNum = bmsVideos.size();
            }
            resultVideos.addAll(bmsVideos.subList(0,videoNum));
            bmsVideos.removeAll(resultVideos);
            //判断同一个用户看过
            //resultVideos = sameUserWatch(resultVideos,bmsVideos,userId);
            //判断是否是同一个商家的视频
            resultVideos = sameBusinessToAfter(resultVideos,bmsVideos);
        }
        //将队列存进redis
        if(bmsVideos.size() > 0) {
            addVideoToRedis(bmsVideos, String.format("user:%s", userId));
        }
        return resultVideos;
    }

    private List<BmsVideo> getVideoIdsByByCityDistrict(String addrCity, String addrDistrict) {
        Map<String,Object> conditionMap = new HashMap<>();
        conditionMap.put("addrCity",addrCity);
        conditionMap.put("addrDistrict",addrDistrict);
        conditionMap.put("isDelete",Constants.COMMON_FLAG_FALSE_INT);
        conditionMap.put("isRelease",Constants.COMMON_FLAG_FALSE_INT);
        conditionMap.put("isOff",Constants.COMMON_FLAG_FALSE_INT);
        List<BmsVideo> bmsVideos = bmsVideoDao.findAll(new SpecificationUtils(conditionMap));
        return bmsVideos;
    }


    public List<BmsVideo> getBmsVideoListSecondByTest(String userId,String latitude,
                                                String longitude,String addrCity,String addrDistrict){
        List<BmsVideo> bmsVideos = new ArrayList<>();
        Map<String,Object> conditionMap = new ConcurrentHashMap<>();
        Set<Integer> videoIds = new HashSet<>();
        videoIds.add(1050);
        videoIds.add(1049);
        videoIds.add(1048);
        videoIds.add(1046);
        videoIds.add(1045);
        videoIds.add(1044);
        videoIds.add(1043);
        conditionMap.put("id_IN",videoIds);
        bmsVideos.addAll(bmsVideoDao.findAll(new SpecificationUtils(conditionMap)));
        //boolean isOpenLocationn = false;
        /*if(StringUtils.isNotBlank(latitude) && StringUtils.isNotBlank(longitude)
                && StringUtils.isNotBlank(addrCity) && StringUtils.isNotBlank(addrDistrict)) {
            //isOpenLocationn = true;
            //当前区3公里内的videoId
            Set<Integer> videoIds = findWithinKilometersDistinctVideoIds(latitude,longitude, addrCity,addrDistrict,new String[]{"0-3"});
            //先找寻3公里内当前区的视频（包含所有等级）
            bmsVideos.addAll(findWithinThreeKilometersDistinct(videoIds,latitude,longitude));
            //先找寻当前市，推过以外的视频id
            Set<Integer> videoIdsThanThreeKm = findThanThreeKmVideo(addrCity,videoIds);
            //再找寻推过以外的视频的A推视频(由近及远)
            bmsVideos.addAll(findThanThreeKmVideoByLevel(latitude,longitude,addrDistrict,videoIdsThanThreeKm,
                    ALevel,BLevel,Elevel,CLevel,DLevel));
            *//*bmsVideos.addAll(findThanThreeKmVideoByLevel(latitude,longitude,addrDistrict,videoIdsThanThreeKm,ALevel));
            //再找寻推过以外的B推视频(由近到远)
            bmsVideos.addAll(findThanThreeKmVideoByLevel(latitude,longitude,addrDistrict,videoIdsThanThreeKm,BLevel));
            //再找寻推过以外的C推视频(由近到远)
            bmsVideos.addAll(findThanThreeKmVideoByLevel(latitude,longitude,addrDistrict,videoIdsThanThreeKm,CLevel));
            //再找寻推过以外的D推视频(由近到远)
            bmsVideos.addAll(findThanThreeKmVideoByLevel(latitude,longitude,addrDistrict,videoIdsThanThreeKm,DLevel));*//*
        }else if(StringUtils.isNotBlank(addrCity) || StringUtils.isNotBlank(addrDistrict)){
            //未开启定位，但选择了区域
            //找出该区域所有的视频的ids
            Set<Integer> videoIds = getVideoIdsByByAddrCityAndAddrDistrict(addrCity,addrDistrict);
            List<BmsVideo> bmsVideoList = new LinkedList<>();
            if(videoIds.size() > 0){
                Sort sort = Sort.by(Sort.Direction.DESC,"likeTimes","newTime");
                bmsVideoList =  bmsVideoDao.findAll(new Specification<BmsVideo>() {
                    @Override
                    public Predicate toPredicate(Root<BmsVideo> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                        Map<String,Object> searchMap = new HashMap<String,Object>(){{
                            put("ids",videoIds);
                        }};
                        criteriaQuery.where(structureSqlBuild(root,criteriaBuilder,searchMap));
                        //加多一个强推
                        return null;
                    }
                },sort);
            }
            Map<String,List<BmsVideo>> bmsVideoMap = doVideoTypeByRecomment(bmsVideoList);
            bmsVideos.addAll(bmsVideoMap.get(ALevel));
            bmsVideos.addAll(bmsVideoMap.get(BLevel));
            bmsVideos.addAll(bmsVideoMap.get(Elevel));
            bmsVideos.addAll(bmsVideoMap.get(CLevel));
            bmsVideos.addAll(bmsVideoMap.get(DLevel));
        }else {
            //未开启定位，也有没有选择区域
            bmsVideos.addAll(findNoLocation());
        }*/
        Integer videoNum = onceVideoNum;
        List<BmsVideo> resultVideos = new LinkedList<>();
        if(bmsVideos.size() > 0) {
            getListPostForVideoList(bmsVideos,userId);
            bmsVideos = postHandleVideoOrder(userId,bmsVideos);
            if(videoNum > bmsVideos.size()){
                videoNum = bmsVideos.size();
            }
            resultVideos.addAll(bmsVideos.subList(0,videoNum));
            bmsVideos.removeAll(resultVideos);
            //判断同一个用户看过
            //resultVideos = sameUserWatch(resultVideos,bmsVideos,userId);
            //判断是否是同一个商家的视频
            //resultVideos = sameBusinessToAfter(resultVideos,bmsVideos);
        }
        //未开启定位
        /*if(!isOpenLocationn && !userId.startsWith(visitorPrfix)){
            //处理重复视频
            final int maxRepeatNum = 3;
            //增加次数
            final int add = 1;
            if(trueResultVideo.size() > 0){
                List<Integer> videoIds = new LinkedList<>();
                for(BmsVideo bmsVideo : trueResultVideo){
                    videoIds.add(bmsVideo.getId());
                }
                //查看这次访问是第几次
                String redisKeyUserVideoNum = Constants.REDIS_KEY_ALREADY_VIDEO_NUM;
                String redisKeyUserVideo = Constants.REDIS_KEY_ALREADY_VIDEO + ":" + userId;
                Double visitNum = redisTemplate.opsForZSet().score(redisKeyUserVideoNum,userId);
                if(visitNum == null){
                    //存储用户访问过的记录
                    redisTemplate.opsForList().leftPushAll(redisKeyUserVideo ,videoIds);
                    redisTemplate.opsForZSet().incrementScore(redisKeyUserVideoNum,userId,add);
                    redisTemplate.expire(redisKeyUserVideo,6,TimeUnit.HOURS);
                    redisTemplate.expire(redisKeyUserVideoNum,6,TimeUnit.HOURS);
                }
                else if(visitNum < maxRepeatNum){
                    //查看用户访问的记录
                    Long size = redisTemplate.opsForList().size(redisKeyUserVideo);
                    List<Integer> visitAlreadVideo = redisTemplate.opsForList().range(redisKeyUserVideo,0,size);
                    List<Integer> newVideo = new LinkedList<>();
                    for(BmsVideo bmsVideo : trueResultVideo){
                        if(!visitAlreadVideo.contains(bmsVideo.getId())){
                            queResultVideo.add(bmsVideo);
                            newVideo.add(bmsVideo.getId());
                        }
                    }
                    List<BmsVideo> recordRemoveBmsVideo = new LinkedList<>();
                    if(queResultVideo.size() < videoNum){
                        final int startIndex = 0;
                        //补满为止
                        while (true) {
                            if((queResultVideo.size() == videoNum)){
                                break;
                            }
                            if(!(bmsVideos.size() > 0)){
                                //既没达到10个,但是又没得补的情况
                                break;
                            }
                            BmsVideo bmsVideo1 = bmsVideos.get(startIndex);
                            if (!visitAlreadVideo.contains(bmsVideo1.getId())) {
                                Integer videoId = bmsVideo1.getId();
                                queResultVideo.add(bmsVideo1);
                                visitAlreadVideo.add(videoId);
                                newVideo.add(videoId);
                                continue;
                            }
                            recordRemoveBmsVideo.add(bmsVideo1);
                            bmsVideos.remove(startIndex);
                        }
                    }
                    if(queResultVideo.size() > 0) {
                        trueResultVideo = queResultVideo;
                        redisTemplate.opsForList().leftPushAll(redisKeyUserVideo, newVideo);
                        redisTemplate.opsForZSet().incrementScore(redisKeyUserVideoNum, userId, add);
                    }else {
                        if(redisTemplate.hasKey(redisKeyUserVideo)){
                            redisTemplate.delete(redisKeyUserVideo);
                        }
                        if(redisTemplate.hasKey(redisKeyUserVideoNum)){
                            redisTemplate.delete(redisKeyUserVideoNum);
                        }
                        bmsVideos = recordRemoveBmsVideo;
                    }

                }else {
                    //第四次访问
                    if(redisTemplate.hasKey(redisKeyUserVideo)){
                        redisTemplate.delete(redisKeyUserVideo);
                    }
                    if(redisTemplate.hasKey(redisKeyUserVideoNum)){
                        redisTemplate.delete(redisKeyUserVideoNum);
                    }
                    redisTemplate.opsForList().leftPushAll(redisKeyUserVideo ,videoIds);
                    redisTemplate.opsForZSet().incrementScore(redisKeyUserVideoNum,userId,add);
                    redisTemplate.expire(redisKeyUserVideo,1,TimeUnit.DAYS);
                    redisTemplate.expire(redisKeyUserVideoNum,1,TimeUnit.DAYS);
                }
            }
        }*/
        //利用模拟用户id,不让用户看过以前刷过的视频
        /*if(trueResultVideo.size() > 0){
            String redisKeyUserVideo = Constants.REDIS_KEY_ALREADY_VIDEO + ":" + userId;
            Long size = redisTemplate.opsForList().size(redisKeyUserVideo);
            List<Integer> visitAlreadVideo = redisTemplate.opsForList().range(redisKeyUserVideo,0,size);
            List<Integer> videoIds = new LinkedList<>();
            for(BmsVideo bmsVideo : trueResultVideo){
                if(!visitAlreadVideo.contains(bmsVideo.getId())){
                    queResultVideo.add(bmsVideo);
                    videoIds.add(bmsVideo.getId());
                }
            }
            List<BmsVideo> recordRemoveBmsVideo = new LinkedList<>();
            if(queResultVideo.size() < videoNum){
                final int startIndex = 0;
                //补满为止
                while (true) {
                    if((queResultVideo.size() == videoNum)){
                        break;
                    }
                    if(!(bmsVideos.size() > 0)){
                        //既没达到10个,但是又没得补的情况
                        break;
                    }
                    BmsVideo bmsVideo1 = bmsVideos.get(startIndex);
                    if (!visitAlreadVideo.contains(bmsVideo1.getId())) {
                        Integer videoId = bmsVideo1.getId();
                        queResultVideo.add(bmsVideo1);
                        visitAlreadVideo.add(videoId);
                        videoIds.add(videoId);
                    }
                    recordRemoveBmsVideo.add(bmsVideo1);
                    bmsVideos.remove(startIndex);
                }
            }
            if(queResultVideo.size() > 0) {
                trueResultVideo = queResultVideo;
                redisTemplate.opsForList().leftPushAll(redisKeyUserVideo, videoIds);
            }else {
                if(redisTemplate.hasKey(redisKeyUserVideo)){
                    redisTemplate.delete(redisKeyUserVideo);
                }
                bmsVideos = recordRemoveBmsVideo;
                Set onceVideoIds = new HashSet();
                for(BmsVideo bmsVideo : trueResultVideo){
                    onceVideoIds.add(bmsVideo.getId());
                }
                redisTemplate.opsForList().leftPushAll(redisKeyUserVideo, onceVideoIds);
            }
        }*/
        //将队列存进redis
        if(bmsVideos.size() > 0) {
            addVideoToRedis(bmsVideos, String.format("user:%s", userId));
        }
        return resultVideos;
    }

    public static boolean getTrueOrFalse(){
        Map<Integer,Boolean> booleanMap = new HashMap<>();
        booleanMap.put(0,false);
        booleanMap.put(1,true);
        return booleanMap.get((int)(Math.random() * 11) % 2);
    }

    private List<BmsVideo> sameUserWatch(List<BmsVideo> resultBmsVideoList, List<BmsVideo> bmsVideos,String userId) {
        Integer videoNum = onceVideoNum;
        String redisKeyUserVideo = Constants.REDIS_KEY_ALREADY_VIDEO  + userId;
        Long size = redisTemplate.opsForList().size(redisKeyUserVideo);
        List<Integer> visitAlreadVideo = redisTemplate.opsForList().range(redisKeyUserVideo,0,size);
        List<Integer> videoIds = new LinkedList<>();
        List<BmsVideo> queResultVideo = new LinkedList<>();
        List<BmsVideo> groupBuyVideo = new LinkedList<>();
        for(BmsVideo bmsVideo : resultBmsVideoList){
            if(!visitAlreadVideo.contains(bmsVideo.getId())){
                queResultVideo.add(bmsVideo);
                videoIds.add(bmsVideo.getId());
            }else {
                if(bmsVideo.getBmsBusiness() != null){
                    BmsBusiness business = bmsVideo.getBmsBusiness();
                    if(business.getIsOpenCoupon() == Constants.COMMON_FLAG_TRUE_INT
                            || business.getIsOpenGroupBuy() == Constants.COMMON_FLAG_TRUE_INT){
                        //String redisKeyUserSeeGroup = Constants.REDIS_KEY_ALREADY_GROUP + userId;
                        if(getTrueOrFalse()) {
                            //groupBuyVideo.add(bmsVideo);
                            //queResultVideo.add(bmsVideo);
                            //videoIds.add(bmsVideo.getId());
                            /*if (redisTemplate.hasKey(redisKeyUserSeeGroup)) {
                                Long groupSize = redisTemplate.opsForList().size(redisKeyUserSeeGroup);
                                redisTemplate.opsForList().rightPush(redisKeyUserSeeGroup, bmsVideo);
                                if (groupSize > 10) {
                                    BmsVideo bv = (BmsVideo) redisTemplate.opsForList().leftPop(redisKeyUserSeeGroup);
                                    queResultVideo.add(bv);
                                    videoIds.add(bv.getId());
                                    count++;
                                }
                            } else {
                                redisTemplate.opsForList().rightPush(redisKeyUserSeeGroup, bmsVideo);
                                redisTemplate.expire(redisKeyUserSeeGroup, 3, TimeUnit.DAYS);
                            }*/
                        }
                    }
                }
            }
        }
        //List<BmsVideo> recordRemoveBmsVideo = new LinkedList<>();
        if(queResultVideo.size() < videoNum){
            //final int startIndex = 0;
            //补满为止
            final int countVideoSize = bmsVideos.size();
            for(int startIndex = 0;startIndex < countVideoSize;startIndex++){
                if((queResultVideo.size() == videoNum)){
                    break;
                }
                if(!(bmsVideos.size() > 0)){
                    //既没达到10个,但是又没得补的情况
                    break;
                }
                BmsVideo bmsVideo1 = bmsVideos.get(startIndex);
                if (!visitAlreadVideo.contains(bmsVideo1.getId())) {
                    Integer videoId = bmsVideo1.getId();
                    queResultVideo.add(bmsVideo1);
                    visitAlreadVideo.add(videoId);
                    videoIds.add(videoId);
                    bmsVideos.remove(startIndex);
                    bmsVideos.add(countVideoSize - 1,bmsVideo1);
                }
                //recordRemoveBmsVideo.add(bmsVideo1);
                //bmsVideos.remove(startIndex);
            }
        }
        if(queResultVideo.size() == videoNum) {
            //随机插入团购视频
            if(groupBuyVideo.size() > 0){
                for(BmsVideo bmsVideo : groupBuyVideo){
                    videoIds.add(bmsVideo.getId());
                    int random = (int)(Math.random() * queResultVideo.size());
                    queResultVideo.add(random,bmsVideo);
                    BmsVideo bv = queResultVideo.get(queResultVideo.size() - 1);
                    bmsVideos.add(0,bmsVideo);
                    videoIds.remove(bv.getId());
                    queResultVideo.remove(queResultVideo.size() - 1);
                }
            }
            resultBmsVideoList = queResultVideo;
            if(redisTemplate.hasKey(redisKeyUserVideo)) {
                redisTemplate.opsForList().leftPushAll(redisKeyUserVideo, videoIds);
            }else {
                redisTemplate.opsForList().leftPushAll(redisKeyUserVideo, videoIds);
                redisTemplate.expire(redisKeyUserVideo,3,TimeUnit.DAYS);
            }
        }else {
            if(redisTemplate.hasKey(redisKeyUserVideo)){
                redisTemplate.delete(redisKeyUserVideo);
            }
            //bmsVideos = recordRemoveBmsVideo;
            Set onceVideoIds = new HashSet();
            for(BmsVideo bmsVideo : resultBmsVideoList){
                onceVideoIds.add(bmsVideo.getId());
            }
            if(onceVideoIds.size() > 0) {
                redisTemplate.opsForList().leftPushAll(redisKeyUserVideo, onceVideoIds);
                redisTemplate.expire(redisKeyUserVideo, 3, TimeUnit.DAYS);
            }
        }
        return resultBmsVideoList;
    }

    /**
     * @Description 获取算法推荐结果
     * @Author: cfx
     * @Date: 2019/8/13
     */
    public List<BmsVideo> getBmsVideoListByAlgorithm(String userId, String latitude, String longitude,
                                               String addrCity, String addrDistrict,Integer isInArea) {
        List<BmsVideo> bmsVideos = new ArrayList<>();
        List<Integer> videoIds = new ArrayList<>();
        //直接去找对应的算法推荐视频
        String recommendUrl = AppConfig.getProperty("syniVideoRecAddress") + "/videoRec";
        Map<String,Object> params = new HashMap<>();
        params.put("uid",userId);
        params.put("addr",addrCity + addrDistrict);
        params.put("latitude",latitude);
        params.put("longitude",longitude);
        params.put("isLoc",isInArea);
        String reponseBody = RestTemplateUtils.postForEntityForJson(recommendUrl,params);
        BmsCommonService.getLogger(this.getClass()).info(reponseBody);
       //System.out.println(reponseBody);
        if(StringUtils.isNotBlank(reponseBody)){
            JSONObject jsonObject = JSON.parseObject(reponseBody);
            if(jsonObject.containsKey("status") && ResultCode.CODE_NORMAL.equals(jsonObject.getString("status"))){
                //去redis里面找
                String userVideoRedisKey = Constants.REDIS_KEY_VIDEO_RECOMMEND + userId;
                long size = redisTemplate.opsForList().size(userVideoRedisKey);
                videoIds = redisTemplate.opsForList().range(userVideoRedisKey,0,size);
                BmsCommonService.getApplicationContext().publishEvent(new VideoEvent("videoGec",addrCity + addrDistrict,longitude,latitude,userId));
            }
        }
        Set<Integer> videoSets = new HashSet<>(videoIds);
        Set<Integer> videoRecords = new HashSet<>();
        if(videoSets.size() > 0) {
            Map<String, Object> conditionMap = new HashMap<>();
            conditionMap.put("id_IN", videoSets);
            conditionMap.put("isDelete", Constants.COMMON_FLAG_FALSE_INT);
            conditionMap.put("isRelease", Constants.COMMON_FLAG_FALSE_INT);
            conditionMap.put("isOff", Constants.COMMON_FLAG_FALSE_INT);
            Set<String> recommends = new HashSet<>();
            recommends.add("E");
            conditionMap.put("recommend_NIN",recommends);
            List<BmsVideo> recVideos = bmsVideoDao.findAll(new SpecificationUtils(conditionMap));
            //按照规定的顺序排序
            if (recVideos != null && recVideos.size() > 0) {
                Map<Integer, BmsVideo> bmsVideoMap = new HashMap<>();
                for (BmsVideo bmsVideo : recVideos) {
                    bmsVideoMap.put(bmsVideo.getId(), bmsVideo);
                }
                for(Integer videoId : videoIds){
                    if(!videoRecords.contains(videoId)) {
                        if(bmsVideoMap.containsKey(videoId)){
                            bmsVideos.add(bmsVideoMap.get(videoId));
                            videoRecords.add(videoId);
                        }
                    }
                }
            }
        }
        Integer videoNum = onceVideoNum;
        List<BmsVideo> resultBmsVideoList = new LinkedList<>();
        if(bmsVideos.size() > 0) {
            getListPostForVideoList(bmsVideos,userId);
            //计算距离
            calculatedDistance(bmsVideos, latitude, longitude);
            //设置团购
            setIsOpenCouponAndGroupBuy(bmsVideos);
            bmsVideos = postHandleVideoOrder(userId,bmsVideos);
            if(videoNum > bmsVideos.size()){
                videoNum = bmsVideos.size();
            }
            List<BmsVideo> resultVideos = bmsVideos.subList(0,videoNum);
            resultBmsVideoList.addAll(resultVideos);
            bmsVideos.removeAll(resultVideos);
            //利用模拟用户id,不让用户看过以前刷过的视频
            //resultBmsVideoList = sameUserWatch(resultBmsVideoList,bmsVideos,userId);
            //同个商家的视频往后偏移
            //resultBmsVideoList = sameBusinessToAfter(resultBmsVideoList,bmsVideos);
            //看过的视频往后移
            //sameUserWatchToBack(resultBmsVideoList,bmsVideos,userId);
        }
        if(bmsVideos.size() > 0) {
            addVideoToRedis(bmsVideos, String.format("user:%s", userId));
        }
        return resultBmsVideoList;
    }

    private List<BmsVideo> postHandleVideoOrder(String userId, List<BmsVideo> bmsVideos) {
        List<BmsVideo> sortVideo = new ArrayList<>();
        if(userId.startsWith(BmsVideoService.visitorPrfix)){
            //执行乱序
            if(bmsVideos.size() > 0){
                Integer endIndex = bmsVideos.size();
                for(int ii = 0;ii < endIndex;ii++){
                    int random = (int)(Math.random() * bmsVideos.size());
                    BmsVideo bmsVideo = bmsVideos.get(random);
                    sortVideo.add(bmsVideo);
                    bmsVideos.remove(random);
                }
            }
        }else {
            sortVideo = bmsVideos;
        }
        return sortVideo;
    }

    /**
     * @Description 记录看过的视频
     * @Author: cfx
     * @Date: 2019/11/2
     */
    private void sameUserWatchToBack(List<BmsVideo> resultBmsVideoList, List<BmsVideo> bmsVideos, String userId) {
        bmsVideos.addAll(resultBmsVideoList);
    }

    /*public List<BmsVideo> getBmsVideoListThird(String userId, String latitude, String longitude,
                                               String addrCity, String addrDistrict,Integer isInArea) {
        List<BmsVideo> bmsVideos = new ArrayList<>();
        List<Integer> videoIds = new ArrayList<>();
        if(isInArea == Constants.COMMON_FLAG_TRUE_INT){
            //直接去找对应的算法推荐视频
            String recommendUrl = AppConfig.getProperty("syniVideoRecAddress") + "/videoRec";
            Map<String,Object> params = new HashMap<>();
            params.put("uid",userId);
            params.put("addr",addrCity + addrDistrict);
            params.put("latitude",latitude);
            params.put("longitude",longitude);
            String reponseBody = RestTemplateUtils.postForEntityForJson(recommendUrl,params);
            System.out.println(reponseBody);
            if(StringUtils.isNotBlank(reponseBody)){
                JSONObject jsonObject = JSON.parseObject(reponseBody);
                if(jsonObject.containsKey("status") && ResultCode.CODE_NORMAL.equals(jsonObject.getString("status"))){
                    //去redis里面找
                    String userVideoRedisKey = Constants.REDIS_KEY_VIDEO_RECOMMEND + userId;
                    long size = redisTemplate.opsForList().size(userVideoRedisKey);
                    videoIds = redisTemplate.opsForList().range(userVideoRedisKey,0,size);
                }
            }
        }else {
            //直接去找对应区域
            if(StringUtils.isNotBlank(addrCity) && StringUtils.isNotBlank(addrDistrict)){
                String redisKey = "rec:no_dis_video_rec";
                String addr = addrCity + addrDistrict;
                if(redisTemplate.hasKey(redisKey)) {
                    String result = redisTemplate.opsForValue().get(redisKey).toString();
                    JSONObject jsonObject = JSON.parseObject(result);
                    if (jsonObject.containsKey(addr)) {
                        videoIds = (List<Integer>) jsonObject.get(addr);
                    }
                }
            }
        }
        Set<Integer> videoSets = new HashSet<>(videoIds);
        Set<Integer> videoRecords = new HashSet<>();
        if(videoSets.size() > 0) {
            Map<String, Object> conditionMap = new HashMap<>();
            conditionMap.put("id_IN", videoSets);
            conditionMap.put("isDelete", Constants.COMMON_FLAG_FALSE_INT);
            conditionMap.put("isRelease", Constants.COMMON_FLAG_FALSE_INT);
            conditionMap.put("isOff", Constants.COMMON_FLAG_FALSE_INT);
            List<BmsVideo> recVideos = bmsVideoDao.findAll(new SpecificationUtils(conditionMap));
            //按照规定的顺序排序
            if (recVideos != null && recVideos.size() > 0) {
                Map<Integer, BmsVideo> bmsVideoMap = new HashMap<>();
                for (BmsVideo bmsVideo : recVideos) {
                    bmsVideoMap.put(bmsVideo.getId(), bmsVideo);
                }
                for(Integer videoId : videoIds){
                    if(!videoRecords.contains(videoId)) {
                        if(bmsVideoMap.containsKey(videoId)){
                            bmsVideos.add(bmsVideoMap.get(videoId));
                            videoRecords.add(videoId);
                        }
                    }
                }
            }
        }
        Integer videoNum = onceVideoNum;
        List<BmsVideo> resultBmsVideoList = new LinkedList<>();
        if(bmsVideos.size() > 0) {
            getListPostForVideoList(bmsVideos,userId);
            //计算距离
            calculatedDistance(bmsVideos, latitude, longitude);
            if(videoNum > bmsVideos.size()){
                videoNum = bmsVideos.size();
            }
            List<BmsVideo> resultVideos = bmsVideos.subList(0,videoNum);
            resultBmsVideoList.addAll(resultVideos);
            bmsVideos.removeAll(resultVideos);
            //利用模拟用户id,不让用户看过以前刷过的视频
            resultBmsVideoList = sameUserWatch(resultBmsVideoList,bmsVideos,userId);
            //同个商家的视频往后偏移
            resultBmsVideoList = sameBusinessToAfter(resultBmsVideoList,bmsVideos);
        }
        if(bmsVideos.size() > 0) {
            addVideoToRedis(bmsVideos, String.format("user:%s", userId));
        }
        return resultBmsVideoList;
    }*/

    public List<BmsVideo> sameBusinessToAfter(List<BmsVideo> resultBmsVideoList, List<BmsVideo> bmsVideos) {
        Integer videoNum = onceVideoNum;
        LinkedList<BmsVideo> afterBmsVideo = new LinkedList<>();
        List<BmsVideo> trueResultVideo = new LinkedList<>();
        Set<Integer> repeatBmsIds = new HashSet<>();
        for(BmsVideo bmsVideo : resultBmsVideoList){
            if(!repeatBmsIds.contains(bmsVideo.getBmsId())){
                repeatBmsIds.add(bmsVideo.getBmsId());
                trueResultVideo.add(bmsVideo);
                continue;
            }
            afterBmsVideo.add(bmsVideo);
        }
        if(trueResultVideo.size() < videoNum){
            final int startIndex = 0;
            //补满为止
            while (true) {
                if((trueResultVideo.size() == videoNum)){
                    break;
                }
                if(!(bmsVideos.size() > 0)){
                    //既没达到10个,但是又没得补的情况
                    if(!(afterBmsVideo.size() > 0)){
                        break;
                    }
                    trueResultVideo.add(afterBmsVideo.pollFirst());
                    continue;
                }
                BmsVideo bmsVideo1 = bmsVideos.get(startIndex);
                if (!repeatBmsIds.contains(bmsVideo1.getBmsId())) {
                    repeatBmsIds.add(bmsVideo1.getBmsId());
                    trueResultVideo.add(bmsVideo1);
                    continue;
                }else{
                    afterBmsVideo.add(bmsVideo1);
                }
                bmsVideos.remove(startIndex);
            }
        }
        if(afterBmsVideo.size() > 0) {
            bmsVideos.addAll(0, afterBmsVideo);
        }
        return trueResultVideo;
    }

    public List<BmsVideo> findNoLocation(){
        List<BmsVideo> bmsVideos = new LinkedList<>();
        String defaultCity = "珠海市";
        Set<Integer> videoIds = getVideoIdsByByAddrCityAndAddrDistrict(defaultCity,"");
        List<BmsVideo> bmsVideoList = new LinkedList<>();
        if(videoIds.size() > 0){
            Sort sort = Sort.by(Sort.Direction.DESC,"likeTimes","newTime");
            bmsVideoList =  bmsVideoDao.findAll(new Specification<BmsVideo>() {
                @Override
                public Predicate toPredicate(Root<BmsVideo> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                    Map<String,Object> searchMap = new HashMap<String,Object>(){{
                        put("ids",videoIds);
                    }};
                    criteriaQuery.where(structureSqlBuild(root,criteriaBuilder,searchMap));
                    //加多一个强推
                    return null;
                }
            },sort);
        }
        Map<String,List<BmsVideo>> bmsVideoMap = doVideoTypeByRecomment(bmsVideoList);
        bmsVideos.addAll(doVideoTypeByDistrict(bmsVideoMap.get(ALevel)));
        bmsVideos.addAll(doVideoTypeByDistrict(bmsVideoMap.get(BLevel)));
        bmsVideos.addAll(doVideoTypeByDistrict(bmsVideoMap.get(Elevel)));
        bmsVideos.addAll(doVideoTypeByDistrict(bmsVideoMap.get(CLevel)));
        bmsVideos.addAll(doVideoTypeByDistrict(bmsVideoMap.get(DLevel)));
        return bmsVideos;
    }

    public List<BmsVideo> doVideoTypeByDistrict(List<BmsVideo> bmsVideos){
        List<BmsVideo> resultVideoList = new LinkedList<>();
        List<BmsVideo> xiangZhouDistinctList = new LinkedList<>();
        List<BmsVideo> douMenDistinctList = new LinkedList<>();
        List<BmsVideo> jinWanDistinctList = new LinkedList<>();
        List<BmsVideo> noDistinct = new LinkedList<>();
        if(bmsVideos != null && bmsVideos.size() > 0){
            for(BmsVideo bmsVideo : bmsVideos){
                if(StringUtils.isNotBlank(bmsVideo.getAddrDistrict())){
                    String addrDistrict = bmsVideo.getAddrDistrict();
                    if(addrDistrict.equals(xiangZhouDistinct)){
                        xiangZhouDistinctList.add(bmsVideo);
                    }else if(addrDistrict.equals(douMenDistinct)){
                        douMenDistinctList.add(bmsVideo);
                    }else if(addrDistrict.equals(jinWanDistinct)){
                        jinWanDistinctList.add(bmsVideo);
                    }
                }else {
                    noDistinct.add(bmsVideo);
                }
            }
        }
        resultVideoList.addAll(xiangZhouDistinctList);
        resultVideoList.addAll(douMenDistinctList);
        resultVideoList.addAll(jinWanDistinctList);
        resultVideoList.addAll(noDistinct);
        return resultVideoList;
    }

    public Map<String,List<BmsVideo>> doVideoTypeByRecomment(List<BmsVideo> bmsVideos){
        Map<String,List<BmsVideo>> bmsVideoMap = new LinkedHashMap<>();
        bmsVideoMap.put(ALevel,new LinkedList<>());
        bmsVideoMap.put(BLevel,new LinkedList<>());
        bmsVideoMap.put(Elevel,new LinkedList<>());
        bmsVideoMap.put(CLevel,new LinkedList<>());
        bmsVideoMap.put(DLevel,new LinkedList<>());
        if(bmsVideos != null && bmsVideos.size() > 0){
            for(BmsVideo bmsVideo : bmsVideos){
                if(StringUtils.isNotBlank(bmsVideo.getRecommend())){
                    String recommentLevel = bmsVideo.getRecommend();
                    if(bmsVideoMap.containsKey(recommentLevel)){
                        bmsVideoMap.get(recommentLevel).add(bmsVideo);
                    }
                }
            }
        }
        return bmsVideoMap;

    }


    public void getListPostForVideoList(List<BmsVideo> bmsVideos,String userId){
        Set videoIds = getVideoIds(bmsVideos);
        findVideoBussessIngoreOpenSet(bmsVideos);
        setUserLikeAndFoot(userId,bmsVideos,videoIds);
        setVideoStatic(bmsVideos);
        //setVideoComment(bmsVideos,videoIds);
        setSendMes(bmsVideos,videoIds);
    }

    public void getListPostHand(List<BmsVideo> bmsVideos,String latitude,
                                String longitude,String userId){
        Set videoIds = getVideoIds(bmsVideos);
        findVideoBussess(bmsVideos);
        calculatedDistance(bmsVideos, latitude, longitude);
        setUserLikeAndFoot(userId,bmsVideos,videoIds);
        setVideoStatic(bmsVideos);
        //setVideoComment(bmsVideos,videoIds);
        setSendMes(bmsVideos,videoIds);
        sortByDistance(bmsVideos);
    }

    public Set getVideoIds(List<BmsVideo> bmsVideos){
        Set videoIds = new HashSet();
        if(bmsVideos != null && bmsVideos.size() > 0){
            for(BmsVideo bmsVideo : bmsVideos){
                videoIds.add(bmsVideo.getId());
            }
        }
        return videoIds;
    }

    public void setSendMes(List<BmsVideo> bmsVideos,Set videoIds) {
        String defaultImg = "00";
        if(bmsVideos != null && bmsVideos.size() > 0){
            Map<Integer,BmsUserVideo> bmsUserVideoMap = new HashMap<>();
            List<BmsUserVideo> bmsUserVideos = bmsUserVideoService.getByVideoIds(videoIds);
            Set<Integer> userIds = new HashSet<>();
            if(bmsUserVideos != null && bmsUserVideos.size() > 0){
                for(BmsUserVideo bmsUserVideo : bmsUserVideos){
                    bmsUserVideoMap.put(bmsUserVideo.getBmsVideoId(),bmsUserVideo);
                    userIds.add(bmsUserVideo.getUserId());
                }
            }
            for(BmsVideo bmsVideo : bmsVideos){
                if(bmsVideo.getFromOrigin() != null) {
                    if (bmsVideo.getFromOrigin().intValue() == Constants.BUSINESS_CLIENT) {
                        bmsVideo.setReleaseRole(BmsDxClientRoleService.bussinessRoleId);
                    }
                }
            }
            Map<Integer,BmsUser> bmsUserMap = bmsUserService.getUserByIds(userIds);
            final int userRole = 1;
            for(BmsVideo bmsVideo : bmsVideos){
                if(bmsUserVideoMap.containsKey(bmsVideo.getId())) {
                    BmsUserVideo bmsUserVideo = bmsUserVideoMap.get(bmsVideo.getId());
                    if (bmsVideo.getReleaseRole() == userRole) {
                        BmsUser bmsUser;
                        if (bmsUserMap.containsKey(bmsUserVideo.getUserId())) {
                            bmsUser = bmsUserMap.get(bmsUserVideo.getUserId());
                        }else {
                            bmsUser = TokenManager.getUser(bmsUserVideo.getUserId());
                        }
                        if(bmsUser != null) {
                            bmsVideo.setReleaseImg(bmsUser.getHeadImg() == null ? defaultImg : bmsUser.getHeadImg());
                            bmsVideo.setReleaseId(bmsUser.getId());
                        }
                    }
                }
            }
        }
    }

    public Map<Integer,List<Integer>> findVideosBussessIds(Set videoIds){
        Map<Integer,List<Integer>> businessIdAndvideoId = new HashMap<>();
        if(videoIds.size() > 0){
            Map<String,Object> condition = new HashMap<>();
            condition.put("isDelete",Constants.COMMON_FLAG_FALSE_INT);
            condition.put("id_IN",videoIds);
            List<BmsVideo> bmsVideos = bmsVideoDao.findAll(new SpecificationUtils(condition));
            if(bmsVideos != null && bmsVideos.size() > 0){
                for(BmsVideo bmsVideo : bmsVideos){
                    if(!businessIdAndvideoId.containsKey(bmsVideo.getBmsId())){
                        businessIdAndvideoId.put(bmsVideo.getBmsId(),new LinkedList<>());
                    }
                    businessIdAndvideoId.get(bmsVideo.getBmsId()).add(bmsVideo.getId());
                }
            }
        }
        return businessIdAndvideoId;
    }

    public void findVideoBussess(List<BmsVideo> bmsVideos) {
        if(bmsVideos != null && bmsVideos.size() > 0){
            Set<Integer> bussinessIds = new HashSet<>();
            for(BmsVideo bmsVideo : bmsVideos){
                if(bmsVideo.getBmsId() != null) {
                    bussinessIds.add(bmsVideo.getBmsId());
                }
            }
            Map<Integer,BmsBusiness> bmsBusinessMap = new HashMap<>();
            if(bussinessIds.size() > 0){
                bmsBusinessMap = bmsBusinessService.findBusinessByIds(bussinessIds);
            }
            for(BmsVideo bmsVideo : bmsVideos){
                if(bmsBusinessMap.containsKey(bmsVideo.getBmsId())){
                    bmsVideo.setBmsBusiness(bmsBusinessMap.get(bmsVideo.getBmsId()));
                }
            }
        }
    }

    public void findVideoBussessIngoreOpenSet(List<BmsVideo> bmsVideos) {
        if(bmsVideos != null && bmsVideos.size() > 0){
            Set<Integer> bussinessIds = new HashSet<>();
            for(BmsVideo bmsVideo : bmsVideos){
                if(bmsVideo.getBmsId() != null) {
                    bussinessIds.add(bmsVideo.getBmsId());
                }
            }
            Map<Integer,BmsBusiness> bmsBusinessMap = new HashMap<>();
            if(bussinessIds.size() > 0){
                bmsBusinessMap = bmsBusinessService.findBusinessByIdsIgnoreSetBuyCoupon(bussinessIds);
            }
            for(BmsVideo bmsVideo : bmsVideos){
                if(bmsBusinessMap.containsKey(bmsVideo.getBmsId())){
                    bmsVideo.setBmsBusiness(bmsBusinessMap.get(bmsVideo.getBmsId()));
                }
            }
        }
    }

    public void setVideoComment(List<BmsVideo> bmsVideos,Set videoIds) {
        /*ZSetOperations zSetOperations = redisTemplate.opsForZSet();
        int start = 0;
        long size = zSetOperations.size(Constants.REDIS_KEY_LIKEDK);*/


    }

    public void setUserLikeAndFoot(String userId,List<BmsVideo> bmsVideos,Set videoIds) {
        //模拟ip的情况不查询
        if(StringUtils.isBlank(userId)){
            return;
        }
        if(userId.startsWith(visitorPrfix)){
            return;
        }
        if(userId.length() > 16){
            return;
        }
        Integer useUserId = Integer.parseInt(userId);
        List<BmsUserVideoLike> bmsUserVideoLikes = bmsUserVideoLikeService.getListByUserIdAndVideoId(useUserId,videoIds);
        List<BmsUserVideoDk> bmsUserVideoDkList = bmsUserVideoDkService.getList(useUserId);
        Set<Integer> likeVideoIds = new HashSet<>();
        Set<Integer> dkBusinessIds = new HashSet<>();
        if(bmsUserVideoLikes != null && bmsUserVideoLikes.size() > 0){
            for(BmsUserVideoLike bmsUserVideoLike: bmsUserVideoLikes){
                likeVideoIds.add(bmsUserVideoLike.getBmsVideoId());
            }
        }
        if(bmsUserVideoDkList != null && bmsUserVideoDkList.size() > 0){
            for(BmsUserVideoDk bmsUserVideoDk: bmsUserVideoDkList){
                dkBusinessIds.add(bmsUserVideoDk.getBmsBusinessId());
            }
        }
        for(BmsVideo bmsVideo : bmsVideos){
            if(likeVideoIds.contains(bmsVideo.getId())){
                bmsVideo.setIsUserLike(userLikeFoot);
            }
            if(dkBusinessIds.contains(bmsVideo.getBmsId())){
                bmsVideo.setIsUserFoot(userLikeFoot);
            }
        }
    }

    public void calculatedDistance(List<BmsVideo> bmsVideos, String latitude, String longitude) {
        if(StringUtils.isNotBlank(latitude) && StringUtils.isNotBlank(longitude)) {
            if (bmsVideos != null && bmsVideos.size() > 0) {
                for (BmsVideo video : bmsVideos) {
                    if(StringUtils.isNotBlank(video.getLatitude()) && StringUtils.isNotBlank(video.getLongitude())) {
                        double lat = Double.parseDouble(video.getLatitude());
                        double lnt = Double.parseDouble(video.getLongitude());
                        double distance = Math.ceil(LocationUtils.getDistance(lat, lnt, Double.parseDouble(latitude), Double.parseDouble(longitude)));
                        video.setDistance(distance);
                    }
                }
            }
        }
    }

    public void sortByDistance(List<BmsVideo> bmsVideos){
        if(bmsVideos != null && bmsVideos.size() > 0){
            Collections.sort(bmsVideos, new Comparator<BmsVideo>() {
                @Override
                public int compare(BmsVideo o1, BmsVideo o2) {
                    if(o1.getDistance() > o2.getDistance()) {
                        return 1;
                    }else if(o1.getDistance() == o2.getDistance()){
                        return 0;
                    }
                    return -1;
                }
            });
        }
    }

    public void setVideoStatic(List<BmsVideo> bmsVideos) {
        if(bmsVideos.size() > 0) {
            for(BmsVideo bmsVideo : bmsVideos) {
                entityManager.unwrap(Session.class).evict(bmsVideo);
            }
            ZSetOperations zSetOperations = redisTemplate.opsForZSet();
            int start = 0;
            long size = zSetOperations.size(Constants.REDIS_KEY_LIKEDK);
            if (size > 0) {
                Map<Integer, BmsVideo> bmsVideoMap = new HashMap<>();
                Map<Integer, BmsBusiness> bmsBusinessMap = new HashMap<>();
                if (bmsVideos.size() > 0) {
                    for (BmsVideo bmsVideo : bmsVideos) {
                        bmsVideoMap.put(bmsVideo.getId(), bmsVideo);
                        BmsBusiness business = bmsVideo.getBmsBusiness();
                        if (business != null) {
                            bmsBusinessMap.put(business.getId(), business);
                        }
                    }
                }
                Set<ZSetOperations.TypedTuple> typedTuples = zSetOperations.rangeWithScores(Constants.REDIS_KEY_LIKEDK, start, size);
                for (ZSetOperations.TypedTuple typedTuple : typedTuples) {
                    String[] dkLikeKey = typedTuple.getValue().toString().split(":");
                    String identify = dkLikeKey[0];
                    Integer id = Integer.parseInt(dkLikeKey[1]);
                    if (BmsVideoService.videoLike.equals(identify)) {
                        if (bmsVideoMap.containsKey(id)) {
                            BmsVideo bmsVideo = bmsVideoMap.get(id);
                            Double likeNum = typedTuple.getScore();
                            bmsVideo.setLikeTimes(bmsVideo.getLikeTimes() == null ? likeNum.intValue()
                                    : bmsVideo.getLikeTimes() + likeNum.intValue());
                        }
                    } else if (BmsVideoService.businessDk.equals(identify)) {
                        if (bmsBusinessMap.containsKey(id)) {
                            BmsBusiness business = bmsBusinessMap.get(id);
                            Double DkNum = typedTuple.getScore();
                            business.setDkTimes(business.getDkTimes() == null ? DkNum.intValue()
                                    : business.getDkTimes() + DkNum.intValue());
                        }
                    } else if (BmsVideoService.videoComment.equals(identify)) {
                        if (bmsVideoMap.containsKey(id)) {
                            BmsVideo bmsVideo = bmsVideoMap.get(id);
                            Double commentNum = typedTuple.getScore();
                            bmsVideo.setCommentNum(bmsVideo.getCommentNum() == null ? commentNum.intValue()
                                    : bmsVideo.getCommentNum() + commentNum.intValue());
                        }
                    }
                }
            }
        }
    }

    public Integer getVideoNowLike(Integer videoId){
        Integer nowLike = 0;
        Optional<BmsVideo> bmsVideoOptional = bmsVideoDao.findById(videoId);
        if(bmsVideoOptional.isPresent()){
            BmsVideo bmsVideo = bmsVideoOptional.get();
            Integer likeTime = (bmsVideo.getLikeTimes() == null) ? 0 : bmsVideo.getLikeTimes();
            nowLike += likeTime;
        }
        ZSetOperations zSetOperations = redisTemplate.opsForZSet();
        int start = 0;
        long size = zSetOperations.size(Constants.REDIS_KEY_LIKEDK);
        if(size > 0) {
            Map<Integer,BmsVideo> bmsVideoMap = new HashMap<>();
            Set<ZSetOperations.TypedTuple> typedTuples = zSetOperations.rangeWithScores(Constants.REDIS_KEY_LIKEDK, start, size);
            for(ZSetOperations.TypedTuple typedTuple : typedTuples){
                String[] dkLikeKey = typedTuple.getValue().toString().split(":");
                String identify = dkLikeKey[0];
                Integer id = Integer.parseInt(dkLikeKey[1]);
                if(BmsVideoService.videoLike.equals(identify)){
                    if(videoId.intValue() == id){
                        Double likeNum = typedTuple.getScore();
                        nowLike += likeNum.intValue();
                    }
                }
            }
        }
        return nowLike;
    }

    public Predicate[] structureSqlBuild(Root<BmsVideo> root,CriteriaBuilder criteriaBuilder,Map<String,Object> searchMap){
        List<Predicate> predicates = new ArrayList<>();
        if(searchMap.containsKey("isRelease")){ predicates.add(criteriaBuilder.equal(root.get("isRelease").as(String.class),searchMap.get("isRelease"))); }
        if(searchMap.containsKey("isDelete")){ predicates.add(criteriaBuilder.equal(root.get("isDelete").as(String.class),searchMap.get("isDelete"))); }
        if(searchMap.containsKey("ids")){
            Set ids = (Set) searchMap.get("ids");
            predicates.add(root.get("id").in(ids));
        }
        if(searchMap.containsKey("ids_no")){
            Set ids = (Set) searchMap.get("ids_no");
            predicates.add(criteriaBuilder.not(root.get("id").in(ids)));
        }
        if(searchMap.containsKey("bmsId")){ predicates.add(criteriaBuilder.equal(root.get("bmsId").as(Integer.class), searchMap.get("bmsId"))); }
        if(searchMap.containsKey("bmsIds")){
            Set bmsIds = (Set) searchMap.get("bmsIds");
            predicates.add(root.get("bmsId").in(bmsIds));
        }
        if(searchMap.containsKey("addrCity")){ predicates.add(criteriaBuilder.equal(root.get("addrCity").as(String.class), searchMap.get("addrCity"))); }
        if(searchMap.containsKey("label")){ predicates.add(criteriaBuilder.equal(root.get("label").as(String.class), searchMap.get("label"))); }
        if(searchMap.containsKey("labels")){ predicates.add(root.get("label").in(searchMap.get("labels"))); }
        if(searchMap.containsKey("recommend")){ predicates.add(criteriaBuilder.equal(root.get("recommend").as(String.class), searchMap.get("recommend"))); }
        if(searchMap.containsKey("isOff")){
            predicates.add(criteriaBuilder.equal(root.get("isOff").as(Integer.class),searchMap.get("isOff")));
        }
        if(searchMap.containsKey("recommends")){
            Set recommends = (Set) searchMap.get("recommends");
            predicates.add(root.get("recommend").in(recommends));
        }
        if(searchMap.containsKey("fromOrigin")){
            predicates.add(criteriaBuilder.equal(root.get("fromOrigin").as(Integer.class),searchMap.get("fromOrigin")));
        }
        if(searchMap.containsKey("fromOrigins")){
            Set fromOrigins = (Set) searchMap.get("fromOrigins");
            predicates.add(root.get("fromOrigin").in(fromOrigins));
        }
        if(searchMap.containsKey("commentNum")) {
            predicates.add(criteriaBuilder.equal(root.get("commentNum").as(Integer.class),searchMap.get("commentNum")));
        }
        return predicates.toArray(new Predicate[predicates.size()]);
    }


    public List<BmsVideo> findBussessisNearby(String latitude, String longitude,List<BmsVideo> bmsVideos){
        LinkedList<BmsVideo> matchVideo = new LinkedList<>();
        String[] selfDistances = rangeDistance.split(",");
        for(String dis : selfDistances) {
            double selfDis = Double.parseDouble(dis) * 1000;
            for(BmsVideo bmsVideo : bmsVideos) {
                if (StringUtils.checkNullAndEmpty(bmsVideo.getLatitude())
                        & StringUtils.checkNullAndEmpty(bmsVideo.getLongitude())) {
                    double lat = Double.parseDouble(bmsVideo.getLatitude());
                    double lnt = Double.parseDouble(bmsVideo.getLongitude());
                    double distance = LocationUtils.getDistance(lat, lnt, Double.parseDouble(latitude), Double.parseDouble(longitude));
                    //公里数以内
                    if(distance < selfDis){
                        matchVideo.add(bmsVideo);
                    }
                }
            }
            if(matchVideo.size() > 0){
                break;
            }
        }
        return matchVideo;
    }

    public List<BmsVideo> getNextVideo(String userId){
        List<BmsVideo> resultBmsVideo = new LinkedList<>();
        LinkedList<BmsVideo> afterBmsVideo = new LinkedList<>();
        Set<Integer> bmsIds = new HashSet<>();
        //从redis获取
        String redisKey = Constants.REDIS_KEY_PREFIX + "user:" + userId;
        if(redisTemplate.hasKey(redisKey)){
            boolean isPickUpEmpty = false;
            while (true) {
                if(resultBmsVideo.size() == onceVideoNum){
                    if(afterBmsVideo.size() > 0) {
                        redisTemplate.opsForList().rightPushAll(redisKey, afterBmsVideo);
                    }
                    break;
                }
                if(isPickUpEmpty){
                    if(!(afterBmsVideo.size() > 0)){
                        break;
                    }
                    resultBmsVideo.add(afterBmsVideo.pollFirst());
                    continue;
                }
                //BmsVideo bmsVideo = (BmsVideo) redisTemplate.opsForList().rightPopAndLeftPush(redisKey, redisKey);
                BmsVideo bmsVideo = (BmsVideo) redisTemplate.opsForList().rightPop(redisKey);
                if(bmsVideo == null){
                    isPickUpEmpty = true;
                    continue;
                }
                if(bmsIds.contains(bmsVideo.getBmsId())){
                    afterBmsVideo.addFirst(bmsVideo);
                    continue;
                }
                resultBmsVideo.add(bmsVideo);
                bmsIds.add(bmsVideo.getBmsId());
            }
        }
        //记录一下看过的视频
        if(resultBmsVideo.size() > 0 ){
            //将看过的放后面
            redisTemplate.opsForList().leftPushAll(redisKey, resultBmsVideo);
            //记录看过的视频
            String redisKeyUserVideo = Constants.REDIS_KEY_ALREADY_VIDEO  + userId;
            List<Integer> videoIds = new LinkedList<>();
            for(BmsVideo bmsVideo : resultBmsVideo){
                videoIds.add(bmsVideo.getId());
            }
            redisTemplate.opsForList().leftPushAll(redisKeyUserVideo, videoIds);
        }
        return resultBmsVideo;
    }


    public void addVideoToRedis(List<BmsVideo> bmsVideos,String userKey) {
        String redisKey = Constants.REDIS_KEY_PREFIX + userKey;
        if(redisTemplate.hasKey(redisKey)){
            redisTemplate.delete(redisKey);
        }
        Integer maxNum = redisMaxVideoNum;
        if (bmsVideos.size() > maxNum){
            //最多缓存maxNum条
            bmsVideos = bmsVideos.subList(0,maxNum);
        }
        if(bmsVideos != null & bmsVideos.size() > 0) {
            redisTemplate.opsForList().leftPushAll(redisKey,bmsVideos);
            redisTemplate.expire(redisKey,1,TimeUnit.DAYS);
        }
    }

    public Set<Integer> findThanThreeKmVideo(String addrCity,String addrDistrict,Set<Integer> videoIds) {
        List<Map<String, Object>> bmsVideos = new LinkedList<>();
        if(videoIds.size() > 0) {
            bmsVideos = bmsVideoDao.findByAddrCityNotInIds(videoIds, addrCity, Constants.COMMON_FLAG_FALSE_INT,
                    Constants.COMMON_FLAG_FALSE_INT,Constants.COMMON_FLAG_FALSE_INT);
        }else {
            bmsVideos = bmsVideoDao.findByAddrCityToFrontShow(addrCity,addrDistrict,Constants.COMMON_FLAG_FALSE_INT,
                    Constants.COMMON_FLAG_FALSE_INT,Constants.COMMON_FLAG_FALSE_INT);
            if(bmsVideos.size() == 0) {
                bmsVideos = bmsVideoDao.findByAddrCityToFrontShow(addrCity, "", Constants.COMMON_FLAG_FALSE_INT,
                        Constants.COMMON_FLAG_FALSE_INT, Constants.COMMON_FLAG_FALSE_INT);
            }
        }
        Set<Integer> resultVideoIds = new HashSet<>();
        if(bmsVideos != null & bmsVideos.size() > 0) {
            for (Map<String, Object> bmsVideo : bmsVideos) {
                resultVideoIds.add(Integer.parseInt(bmsVideo.get("id").toString()));
            }
        }
        return resultVideoIds;
    }

    public List<BmsVideo> findThanThreeKmVideoByLevel(String latitude, String longitude,String addrDistrict,Set<Integer> videoIds,
                                                      String... levels){
        List<BmsVideo> resultBmsVideoList = new LinkedList<>();
        List<BmsVideo> bmsVideoList = new LinkedList<>();
        Set<String> setLevels = new HashSet<>();
        if(!(levels.length > 0)){
            return resultBmsVideoList;
        }
        for(String level : levels){
            setLevels.add(level);
        }
        if(videoIds.size() > 0){
            Sort sort = Sort.by(Sort.Direction.DESC,"likeTimes","newTime");
            bmsVideoList =  bmsVideoDao.findAll(new Specification<BmsVideo>() {
                @Override
                public Predicate toPredicate(Root<BmsVideo> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                    Map<String,Object> searchMap = new HashMap<String,Object>(){{
                        put("ids",videoIds);
                        put("recommends",setLevels);
                    }};
                    criteriaQuery.where(structureSqlBuild(root,criteriaBuilder,searchMap));
                    //加多一个强推
                    return null;
                }
            },sort);
        }
        Map<String,List<BmsVideo>> bmsVideoMaps = doVideoTypeByRecomment(bmsVideoList);
        for(Map.Entry<String,List<BmsVideo>> bmsVideoMap : bmsVideoMaps.entrySet()){
            List<BmsVideo> currentDistrictVideoList = new LinkedList<>();
            List<BmsVideo> otherDistrictVideoList = new LinkedList<>();
            List<BmsVideo> bmsVideos = bmsVideoMap.getValue();
            if(bmsVideos != null && bmsVideos.size() > 0){
                for(BmsVideo bmsVideo : bmsVideos){
                    boolean isOther = true;
                    if(StringUtils.isNotBlank(bmsVideo.getAddrDistrict())){
                        String tmpAddrDis = bmsVideo.getAddrDistrict();
                        if(tmpAddrDis.equals(addrDistrict)){
                            currentDistrictVideoList.add(bmsVideo);
                            isOther = false;
                        }
                    }
                    if(isOther){
                        otherDistrictVideoList.add(bmsVideo);
                    }
                }
                calculatedDistance(currentDistrictVideoList,latitude,longitude);
                sortByDistance(currentDistrictVideoList);
                resultBmsVideoList.addAll(currentDistrictVideoList);
                calculatedDistance(otherDistrictVideoList,latitude,longitude);
                sortByDistance(otherDistrictVideoList);
                resultBmsVideoList.addAll(otherDistrictVideoList);
            }
        }
        return resultBmsVideoList;
    }

    public List<BmsVideo> getMoreThreeKmVideoByLevel(String addrDistrict,List<BmsVideo> bmsVideoList,
                                                      String... levels){
        List<BmsVideo> resultBmsVideoList = new LinkedList<>();
        Set<String> setLevels = new HashSet<>();
        if(!(levels.length > 0)){
            return resultBmsVideoList;
        }
        for(String level : levels){
            setLevels.add(level);
        }
        Map<String,List<BmsVideo>> bmsVideoMaps = doVideoTypeByRecomment(bmsVideoList);
        for(Map.Entry<String,List<BmsVideo>> bmsVideoMap : bmsVideoMaps.entrySet()){
            List<BmsVideo> currentDistrictVideoList = new LinkedList<>();
            List<BmsVideo> otherDistrictVideoList = new LinkedList<>();
            List<BmsVideo> bmsVideos = bmsVideoMap.getValue();
            if(bmsVideos != null && bmsVideos.size() > 0){
                for(BmsVideo bmsVideo : bmsVideos){
                    boolean isOther = true;
                    if(StringUtils.isNotBlank(bmsVideo.getAddrDistrict())){
                        String tmpAddrDis = bmsVideo.getAddrDistrict();
                        if(tmpAddrDis.equals(addrDistrict)){
                            currentDistrictVideoList.add(bmsVideo);
                            isOther = false;
                        }
                    }
                    if(isOther){
                        otherDistrictVideoList.add(bmsVideo);
                    }
                }
                sortByDistance(currentDistrictVideoList);
                resultBmsVideoList.addAll(currentDistrictVideoList);
                sortByDistance(otherDistrictVideoList);
                resultBmsVideoList.addAll(otherDistrictVideoList);
            }
        }
        return resultBmsVideoList;
    }

    /*public List<BmsVideo> findThanThreeKmVideoByLevel(String latitude, String longitude,String addrDistrict,Set<Integer> videoIds,String level) {
        List<BmsVideo> resultBmsVideoList = new LinkedList<>();
        List<BmsVideo> bmsVideoList = new LinkedList<>();
        if(videoIds.size() > 0){
            Integer[] ids = videoIds.toArray(new Integer[videoIds.size()]);
            Sort sort = Sort.by(Sort.Direction.DESC,"likeTimes","newTime");
            bmsVideoList =  bmsVideoDao.findAll(new Specification<BmsVideo>() {
                @Override
                public Predicate toPredicate(Root<BmsVideo> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                    Map<String,Object> searchMap = new HashMap<String,Object>(){{
                        put("ids",ids);
                        put("recommend",level);
                    }};
                    criteriaQuery.where(structureSqlBuild(root,criteriaBuilder,searchMap));
                    //加多一个强推
                    return null;
                }
            },sort);
        }
        List<BmsVideo> currentDistrictVideoList = new LinkedList<>();
        List<BmsVideo> otherDistrictVideoList = new LinkedList<>();
        if(bmsVideoList != null && bmsVideoList.size() > 0){
            for(BmsVideo bmsVideo : bmsVideoList){
                if(StringUtils.isNotBlank(bmsVideo.getAddrDistrict())){
                    String tmpAddrDis = bmsVideo.getAddrDistrict();
                    if(tmpAddrDis.equals(addrDistrict)){
                        currentDistrictVideoList.add(bmsVideo);
                    }
                }else {
                    otherDistrictVideoList.add(bmsVideo);
                }
            }
        }
        //找出当前区的视频
        calculatedDistance(currentDistrictVideoList,latitude,longitude);
        sortByDistance(currentDistrictVideoList);
        resultBmsVideoList.addAll(currentDistrictVideoList);
        calculatedDistance(otherDistrictVideoList,latitude,longitude);
        sortByDistance(otherDistrictVideoList);
        resultBmsVideoList.addAll(otherDistrictVideoList);
        return resultBmsVideoList;
    }*/

    public List<BmsVideo> findThanThreeKmRecommendGen(String latitude, String longitude, Set<Integer> videoIds) {
        List<BmsVideo> bmsVideoList = new LinkedList<>();
        if(videoIds.size() > 0){
            Sort sort = Sort.by(Sort.Direction.DESC,"likeTimes","newTime");
            bmsVideoList =  bmsVideoDao.findAll(new Specification<BmsVideo>() {
                @Override
                public Predicate toPredicate(Root<BmsVideo> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                    //criteriaQuery.where(structureSqlBuild(root,criteriaBuilder,ids,"A"));
                    //加多一个强推
                    return null;
                }
            },sort);
        }
        calculatedDistance(bmsVideoList,latitude,longitude);
        sortByDistance(bmsVideoList);
        return bmsVideoList;

    }

    public Set<Integer> getVideoIdsByByAddrCityAndAddrDistrict(String addrCity,String addrDistrict){
        Set<Integer> videoIds = new HashSet<>();
        List<Map<String, Object>> bmsIdsMap = findByAddrCityAndAddrDistrict(addrCity,addrDistrict);
        if(bmsIdsMap!= null && bmsIdsMap.size() > 0){
            for (Map<String, Object> bmsVideo : bmsIdsMap) {
                videoIds.add(Integer.parseInt(bmsVideo.get("id").toString()));
            }
        }
        return videoIds;
    }

    public List<Map<String, Object>> findByAddrCityAndAddrDistrict(String addrCity,String addrDistrict){
        StringBuilder stringBuilder = new StringBuilder(Constants.REDIS_KEY_PREFIX + "video:idAndGps");
        if(!"".equals(addrCity)){
            String areaCode = String.valueOf(addrCity.hashCode()).substring(0,4);
            stringBuilder.append(":" + areaCode);
            if(!"".equals(addrDistrict)){
                String district = String.valueOf(addrDistrict.hashCode()).substring(0,4);
                stringBuilder.append(":" + district);
            }
        }
        String redisKey = stringBuilder.toString();
        List<Map<String, Object>> bmsVideos;
        if(redisTemplate.hasKey(redisKey)){
            //从缓存中获取
            bmsVideos = (List<Map<String, Object>>) redisTemplate.opsForValue().get(redisKey);
        }else {
            //if(!"".equals())
            bmsVideos = bmsVideoDao.findByAddrCityToFrontShow(addrCity,addrDistrict,Constants.COMMON_FLAG_FALSE_INT,
                    Constants.COMMON_FLAG_FALSE_INT,Constants.COMMON_FLAG_FALSE_INT);
            List<Map<String,Object>> redisData = new LinkedList<>();
            if(bmsVideos != null & bmsVideos.size() > 0) {
                for(Map<String,Object> objectMap : bmsVideos){
                    Map<String,Object> videoLatLngMap = new HashMap<>();
                    videoLatLngMap.put("id",objectMap.get("id"));
                    videoLatLngMap.put("latitude",objectMap.get("latitude"));
                    videoLatLngMap.put("longitude",objectMap.get("longitude"));
                    redisData.add(videoLatLngMap);
                }
                redisTemplate.opsForValue().set(redisKey,redisData,12, TimeUnit.HOURS);
            }
        }
        return bmsVideos;
    }

    public Set<Integer> findWithinKilometersDistinctVideoIds(String latitude, String longitude,
                                                          String addrCity,String addrDistrict,String[] selfDistances){
        Set<Integer> videoIds = new HashSet<>();
        List<Map<String, Object>> bmsVideos = findByAddrCityAndAddrDistrict(addrCity,addrDistrict);
        if(bmsVideos != null & bmsVideos.size() > 0) {
            if(StringUtils.isNotBlank(latitude) && StringUtils.isNotBlank(longitude)) {
                for (String dis : selfDistances) {
                    String[] myDis = dis.split("-");
                    double minSelfDis = Double.parseDouble(myDis[0]) * 1000;
                    double maxSelfDis = Double.parseDouble(myDis[1]) * 1000;
                    for (Map<String, Object> bmsVideo : bmsVideos) {
                        if (bmsVideo.containsKey("latitude") && StringUtils.checkNullAndEmpty(bmsVideo.get("latitude"))
                                && bmsVideo.containsKey("longitude") && StringUtils.checkNullAndEmpty(bmsVideo.get("longitude"))) {
                            double lat = Double.parseDouble(bmsVideo.get("latitude").toString());
                            double lnt = Double.parseDouble(bmsVideo.get("longitude").toString());
                            double distance = LocationUtils.getDistance(lat, lnt, Double.parseDouble(latitude), Double.parseDouble(longitude));
                            //公里数以内
                            if (distance >= minSelfDis && distance < maxSelfDis) {
                                videoIds.add(Integer.parseInt(bmsVideo.get("id").toString()));
                            }
                        }
                    }
                }
            }
        }
        return videoIds;
    }

    public Map<String,List<BmsVideo>> getThreeKmVideo(String latitude, String longitude,
                                                             List<BmsVideo> bmsVideos){
        Map<String,List<BmsVideo>> recommendVideo = new HashMap<>();
        recommendVideo.put("threeKmVideo",new LinkedList<>());
        recommendVideo.put("otherVideo",new LinkedList<>());
        if(bmsVideos != null & bmsVideos.size() > 0) {
            if(StringUtils.isNotBlank(latitude) && StringUtils.isNotBlank(longitude)) {
                for (BmsVideo video : bmsVideos) {
                    if(StringUtils.isNotBlank(video.getLatitude()) && StringUtils.isNotBlank(video.getLongitude())) {
                        double lat = Double.parseDouble(video.getLatitude());
                        double lnt = Double.parseDouble(video.getLongitude());
                        double distance = Math.ceil(LocationUtils.getDistance(lat, lnt, Double.parseDouble(latitude), Double.parseDouble(longitude)));
                        video.setDistance(distance);
                        if (distance >= 0d && distance < 3000d) {
                            recommendVideo.get("threeKmVideo").add(video);
                        }else {
                            recommendVideo.get("otherVideo").add(video);
                        }
                    }
                }
            }
        }
        return recommendVideo;
    }

    public List<BmsVideo> findWithinThreeKilometersDistinct(Set<Integer> videoIds,String latitude,String longitude){
        List<BmsVideo> bmsVideos = new LinkedList<>();
        if(videoIds.size() > 0){
            Map<String,Object> conditionMap = new HashMap<>();
            conditionMap.put("id_IN",videoIds);
            Sort sort = Sort.by(Sort.Direction.DESC,"likeTimes","newTime");
            bmsVideos = bmsVideoDao.findAll(new SpecificationUtils(conditionMap),sort);
        }
        calculatedDistance(bmsVideos,latitude,longitude);
        sortByDistance(bmsVideos);
        return bmsVideos;
    }

    public List<BmsVideo> findWithinThreeKilometersDistinct(Double start,Double end,String lnt,String lat,Set videoIds){
        long startTime = System.currentTimeMillis();
        List<BmsVideo> bmsVideos = bmsVideoDao.findLessThanThreeKmVideo(videoIds,start, end, lnt, lat);
        long endTime = System.currentTimeMillis();
        System.out.println("花费秒数：" + (endTime - startTime));
        calculatedDistance(bmsVideos,lat,lnt);
        sortByDistance(bmsVideos);
        return bmsVideos;
    }


    public Integer[] findBussessisNearby(String latitude, String longitude,
                                         String addrCity,String addrDistrict) {
        StringBuilder stringBuilder = new StringBuilder(Constants.REDIS_KEY_PREFIX + "video:idAndGps");
        if(!"".equals(addrCity)){
            String areaCode = String.valueOf(addrCity.hashCode()).substring(0,4);
            stringBuilder.append(":" + areaCode);
            if(!"".equals(addrDistrict)){
                String district = String.valueOf(addrDistrict.hashCode()).substring(0,4);
                stringBuilder.append(":" + district);
            }
        }
        String redisKey = stringBuilder.toString();
        Set<Integer> videoIds = new HashSet<>();
        String[] selfDistances = rangeDistance.split(",");
        List<Map<String, Object>> bmsVideos;
        if(redisTemplate.hasKey(redisKey)){
            //从缓存中获取
            bmsVideos = (List<Map<String, Object>>) redisTemplate.opsForValue().get(redisKey);
        }else {
            //if(!"".equals())
            bmsVideos = bmsVideoDao.findByAddrCityToFrontShow(addrCity,addrDistrict,Constants.COMMON_FLAG_FALSE_INT,
                    Constants.COMMON_FLAG_FALSE_INT,Constants.COMMON_FLAG_FALSE_INT);
            List<Map<String,Object>> redisData = new LinkedList<>();
            if(bmsVideos != null & bmsVideos.size() > 0) {
                for(Map<String,Object> objectMap : bmsVideos){
                    Map<String,Object> videoLatLngMap = new HashMap<>();
                    videoLatLngMap.put("id",objectMap.get("id"));
                    videoLatLngMap.put("latitude",objectMap.get("latitude"));
                    videoLatLngMap.put("longitude",objectMap.get("longitude"));
                    redisData.add(videoLatLngMap);
                }
                redisTemplate.opsForValue().set(redisKey,redisData,12, TimeUnit.HOURS);
            }
        }
        if(bmsVideos != null & bmsVideos.size() > 0) {
            if(StringUtils.isNotBlank(latitude) && StringUtils.isNotBlank(longitude)) {
                for (String dis : selfDistances) {
                    double selfDis = Double.parseDouble(dis) * 1000;
                    for (Map<String, Object> bmsVideo : bmsVideos) {
                        if (bmsVideo.containsKey("latitude") & StringUtils.checkNullAndEmpty(bmsVideo.get("latitude"))
                                & bmsVideo.containsKey("longitude") & StringUtils.checkNullAndEmpty(bmsVideo.get("longitude"))) {
                            double lat = Double.parseDouble(bmsVideo.get("latitude").toString());
                            double lnt = Double.parseDouble(bmsVideo.get("longitude").toString());
                            double distance = LocationUtils.getDistance(lat, lnt, Double.parseDouble(latitude), Double.parseDouble(longitude));
                            //公里数以内
                            if (distance < selfDis) {
                                videoIds.add(Integer.parseInt(bmsVideo.get("id").toString()));
                            }
                        }
                    }
                    if (videoIds.size() > redisMaxVideoNum) {
                        break;
                    }
                }
            }
        }
        if(videoIds.size() < minVideoNum){
            //自动推荐最新，最多点赞数的商家(从当前区域,延伸到当前城市)
            List<Map<String,Object>> newestHotVideos = bmsVideoDao.findByNewestAndHottest(addrCity,addrDistrict,Constants.COMMON_FLAG_FALSE, Constants.COMMON_FLAG_FALSE);
            if(newestHotVideos != null && newestHotVideos.size() > 0){
                for(Map<String,Object> newestHotVideo : newestHotVideos){
                    videoIds.add(Integer.parseInt(newestHotVideo.get("id").toString()));
                }
            }else {
                //查询当前城市
                newestHotVideos = bmsVideoDao.findByNewestAndHottest(addrCity,"",Constants.COMMON_FLAG_FALSE,Constants.COMMON_FLAG_FALSE);
                if(newestHotVideos != null && newestHotVideos.size() > 0){
                    for(Map<String,Object> newestHotVideo : newestHotVideos){
                        videoIds.add(Integer.parseInt(newestHotVideo.get("id").toString()));
                    }
                }else {
                    newestHotVideos = bmsVideoDao.findByNewestAndHottest("","",Constants.COMMON_FLAG_FALSE,Constants.COMMON_FLAG_FALSE);
                    //其他城市（数据库中最新点赞数最多的商家）
                    if(newestHotVideos != null && newestHotVideos.size() > 0){
                        for(Map<String,Object> newestHotVideo : newestHotVideos){
                            videoIds.add(Integer.parseInt(newestHotVideo.get("id").toString()));
                        }
                    }else {
                        videoIds.add(-1);
                    }
                }

            }
        }
        return videoIds.toArray(new Integer[videoIds.size()]);
    }

    @Transactional
    public Map<String,Object> searchVideo(String userId,Integer businessId,String latitude,
                                      String longitude,String searchText,
                                      Integer page,Integer pageSize) {
        if(pageSize == null){
            pageSize = 9;
        }
        final String recommend = "A";
        List<BmsVideo> bmsVideos = new LinkedList<>();
        List<BmsVideo> recommendBmsVideos = new LinkedList<>();
        Integer recommendNum = 0;
        Integer isLastPage = Constants.COMMON_FLAG_TRUE_INT;
        BmsBusiness business;
        List<Map<String,Object>> businessMaps = new LinkedList<>();
        if(businessId != null){
            //通过商家搜索
            Optional<BmsBusiness> bmsBusinessOp = bmsBusinessService.getBaseDao().findById(businessId);
            if(bmsBusinessOp.isPresent()) {
                business = bmsBusinessOp.get();
                recordHistorySearch(userId,business.getVendorName());
                countHotSearch(business.getVendorName());
                Map<String,Object> businessMap = new HashMap<>();
                businessMap.put("id",business.getId());
                businessMap.put("addr_city",business.getAddrCity());
                businessMap.put("label",business.getLabel());
                businessMaps.add(businessMap);
                Pageable pageable = BmsCommonService.getPageable(page, pageSize, Sort.Direction.DESC, "likeTimes", "newTime");
                Page<BmsVideo> bmsVideoPage = bmsVideoDao.findAll(new Specification<BmsVideo>() {
                    @Override
                    public Predicate toPredicate(Root<BmsVideo> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                        Map<String,Object> searchMap = new HashMap<String,Object>(){{
                            put("isRelease",Constants.COMMON_FLAG_FALSE);
                            put("isDelete",Constants.COMMON_FLAG_FALSE);
                            put("bmsId",businessId);
                            put("isOff",Constants.COMMON_FLAG_FALSE);
                        }};
                        criteriaQuery.where(structureSqlBuild(root,criteriaBuilder,searchMap));
                        return null;
                    }
                },pageable);
                bmsVideos.addAll(bmsVideoPage.getContent());
                if(page < bmsVideoPage.getTotalPages()){
                    isLastPage = Constants.COMMON_FLAG_FALSE_INT;
                }
            }
        }else {
            //通过内容搜索
            if(searchText != null) {
                if(searchText.length() > 100){
                    return ResultMapHelper.result(ResultCode.CODE_VIDEO_SEARCH_REPORT_TEXT,"视频搜索内容过长");
                }
                String searchTrueText = "%" + searchText + "%";
                businessMaps = bmsBusinessService.getBaseDao().findByVendorNameLikeAndIsDeleteAndIsUnload(searchTrueText,
                        Integer.parseInt(Constants.COMMON_FLAG_FALSE),Integer.parseInt(Constants.COMMON_FLAG_FALSE));
                recordHistorySearch(userId,searchText);
                countHotSearch(searchText);
                if(businessMaps != null && businessMaps.size() > 0){
                    //找到了相关商家(收集商家视频)
                    Set businessIds = new HashSet();
                    for(Map<String,Object> businessMap : businessMaps){
                        businessIds.add(Integer.parseInt(businessMap.get("id").toString()));
                    }
                    if(businessIds.size() > 0){
                        Pageable pageable = PageRequest.of(page - 1,pageSize, Sort.Direction.DESC,"likeTimes","newTime");
                        Page<BmsVideo> bmsVideoPage = bmsVideoDao.findAll(new Specification<BmsVideo>() {
                            @Override
                            public Predicate toPredicate(Root<BmsVideo> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                                Map<String,Object> searchMap = new HashMap<String,Object>(){{
                                    put("isRelease",Constants.COMMON_FLAG_FALSE);
                                    put("isDelete",Constants.COMMON_FLAG_FALSE);
                                    put("bmsIds",businessIds);
                                    put("isOff",Constants.COMMON_FLAG_FALSE);
                                }};
                                criteriaQuery.where(structureSqlBuild(root,criteriaBuilder,searchMap));
                                return null;
                            }
                        },pageable);
                        bmsVideos.addAll(bmsVideoPage.getContent());
                        if(page < bmsVideoPage.getTotalPages()){
                            isLastPage = Constants.COMMON_FLAG_FALSE_INT;
                        }
                    }
                }
            }
        }
        //开始推荐
        if(bmsVideos.size() == recommendNum || (isLastPage == Constants.COMMON_FLAG_TRUE_INT)){
            //进行视频的推荐(推荐10条视频)
            Set<Integer> dataHavVideoIds = new HashSet<>();
            dataHavVideoIds.add(0);
            for(BmsVideo bmsVideo : bmsVideos){
                dataHavVideoIds.add(bmsVideo.getId());
            }
            if(businessMaps.size() > 0){
                //判断存在商家是否是同一个城市
                Set addrCitys = new HashSet();
                Set labelList = new HashSet();
                for(Map<String,Object> businessMap : businessMaps){
                    if(StringUtils.checkNullAndEmpty(businessMap.get("addr_city"))) {
                        addrCitys.add(businessMap.get("addr_city"));
                    }
                    if(StringUtils.checkNullAndEmpty(businessMap.get("label"))){
                        labelList.add(businessMap.get("label").toString());
                    }
                }
                String labels = StringUtils.join(labelList,",");
                if(addrCitys.size() == 1){
                    //同一个城市
                    String addrCity = addrCitys.iterator().next().toString();
                    if(StringUtils.isNotBlank(labels)){
                        //有标签
                        Pageable pageable = PageRequest.of(0,10, Sort.Direction.DESC,"likeTimes","newTime");
                        recommendBmsVideos.addAll(bmsVideoDao.findAll(new Specification<BmsVideo>() {
                            @Override
                            public Predicate toPredicate(Root<BmsVideo> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                                Map<String,Object> searchMap = new HashMap<String,Object>(){{
                                    put("isRelease",Constants.COMMON_FLAG_FALSE);
                                    put("isDelete",Constants.COMMON_FLAG_FALSE);
                                    put("isOff",Constants.COMMON_FLAG_FALSE);
                                    put("addrCity",addrCity);
                                    put("labels",labelList);
                                    put("ids_no",dataHavVideoIds);
                                }};
                                criteriaQuery.where(structureSqlBuild(root,criteriaBuilder,searchMap));
                                return null;
                            }
                        },pageable).getContent());
                        if(recommendBmsVideos.size() < 10){
                            pageable = PageRequest.of(0,10 - recommendBmsVideos.size(), Sort.Direction.DESC,"likeTimes","newTime");
                            for(BmsVideo bmsVideo : recommendBmsVideos){
                                dataHavVideoIds.add(bmsVideo.getId());
                            }
                            recommendBmsVideos.addAll(bmsVideoDao.findByIdNotInAndAddrCityAndRecommendAndIsDeleteAndIsRelease(dataHavVideoIds,
                                    addrCity,recommend,isDelete,isRelease,pageable));
                        }
                    }else {
                        //无标签
                        Pageable pageable = BmsCommonService.getPageable(0,10, Sort.Direction.DESC,"likeTimes","newTime");
                        recommendBmsVideos.addAll(bmsVideoDao.findAll(new Specification<BmsVideo>() {
                            @Override
                            public Predicate toPredicate(Root<BmsVideo> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                                Map<String,Object> searchMap = new HashMap<String,Object>(){{
                                    put("isRelease",Constants.COMMON_FLAG_FALSE);
                                    put("isDelete",Constants.COMMON_FLAG_FALSE);
                                    put("isOff",Constants.COMMON_FLAG_FALSE);
                                    put("addrCity",addrCity);
                                    put("recommend",recommend);
                                    put("ids_no",dataHavVideoIds);
                                }};
                                criteriaQuery.where(structureSqlBuild(root,criteriaBuilder,searchMap));
                                return null;
                            }
                        },pageable).getContent());
                    }
                }else if(businessMaps.size() > 1){
                    //多个城市
                    if(StringUtils.isNotBlank(labels)){
                        //多个城市有标签
                        Pageable pageable = PageRequest.of(0,10, Sort.Direction.DESC,"likeTimes","newTime");
                        recommendBmsVideos.addAll(bmsVideoDao.findAll(new Specification<BmsVideo>() {
                            @Override
                            public Predicate toPredicate(Root<BmsVideo> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                                Map<String,Object> searchMap = new HashMap<String,Object>(){{
                                    put("isRelease",Constants.COMMON_FLAG_FALSE);
                                    put("isDelete",Constants.COMMON_FLAG_FALSE);
                                    put("isOff",Constants.COMMON_FLAG_FALSE);
                                    put("labels",labelList);
                                    put("ids_no",dataHavVideoIds);
                                }};
                                criteriaQuery.where(structureSqlBuild(root,criteriaBuilder,searchMap));
                                return null;
                            }
                        },pageable).getContent());
                        if(recommendBmsVideos.size() < 10){
                            //补足
                            getDefaultRecommendLevel(recommendBmsVideos);
                        }
                    }else {
                        //多个城市无标签
                        getDefaultRecommendLevel(recommendBmsVideos);
                    }
                }else if(businessMaps.size() == 0){
                    //没有城市
                    getDefaultRecommendLevel(recommendBmsVideos);
                }
            }else {
                //没有查询到店铺的情况
                getDefaultRecommendLevel(recommendBmsVideos);
            }
        }
       getListPostHand(bmsVideos,latitude,longitude,userId);
       getListPostHand(recommendBmsVideos,latitude,longitude,userId);
       Map<String,Object> userData = new HashMap<>();
       userData.put("isLastPage",isLastPage);
       userData.put("recommendVideo",recommendBmsVideos);
       return ResultMapHelper.success(bmsVideos,userData,"查找成功");
    }

    public void getDefaultRecommendLevel(List<BmsVideo> recommendBmsVideos){
        String[] recommendLevels = {"A","B","C","D"};
        for(int ii = 0;ii < recommendLevels.length;ii++){
            Pageable pageable = BmsCommonService.getPageable(1,10 - recommendBmsVideos.size(), Sort.Direction.DESC,"likeTimes","newTime");
            String recommendLevel = recommendLevels[ii];
            recommendBmsVideos.addAll(bmsVideoDao.findByIsDeleteAndIsReleaseAndRecommend(Integer.parseInt(Constants.COMMON_FLAG_FALSE),
                    Integer.parseInt(Constants.COMMON_FLAG_FALSE), recommendLevel, pageable));
            if(recommendBmsVideos.size() >= 10){
                break;
            }
        }
    }

    public void recordHistorySearch(String userId,String searchText) {
        if(userId == null || userId.startsWith(BmsVideoService.visitorPrfix)) {
            return;
        }
        bmsSearchLogService.addUserSearchHistroy(Integer.parseInt(userId),searchText,Constants.RECORD_TEXT);
    }

    public void recordHistorySearch_V2(String userId,String searchText,Integer searchType) {
        if(userId == null || userId.startsWith(BmsVideoService.visitorPrfix)) {
            return;
        }
        bmsSearchLogService.addUserSearchHistroy(Integer.parseInt(userId),searchText,searchType);
    }

    public void countHotSearch(String searchText) {
        String redisKey = Constants.REDIS_KEY_PREFIX + "hostSearch";
        Integer auto_increase = 1;
        if(redisTemplate.hasKey(redisKey)){
            redisTemplate.opsForZSet().incrementScore(redisKey,searchText,auto_increase);
        }else {
            redisTemplate.opsForZSet().incrementScore(redisKey,searchText,auto_increase);
            redisTemplate.expire(redisKey,3,TimeUnit.HOURS);
        }
    }

    public Map<String,Object> findDetailVideo(String userIdentify, String latitude, String longitude,Integer videoId) {
        Map<String,Object> conditionMap = new HashMap<>();
        conditionMap.put("id",videoId);
        conditionMap.put("isDelete",Constants.COMMON_FLAG_FALSE_INT);
        conditionMap.put("isRelease",Constants.COMMON_FLAG_FALSE_INT);
        conditionMap.put("isOff",Constants.COMMON_FLAG_FALSE_INT);
        List<BmsVideo> bmsVideos = bmsVideoDao.findAll(new SpecificationUtils(conditionMap));
        getListPostHand(bmsVideos,latitude,longitude,userIdentify);

        //设置团购
        setIsOpenCouponAndGroupBuy(bmsVideos);
        if(!(bmsVideos != null && bmsVideos.size() > 0)) {
            return ResultMapHelper.result(ResultCode.CODE_VIDEO_NO_EXIST,"视频已被下线或删除");
        }
        return ResultMapHelper.success(bmsVideos.get(0),ResultMsg.MSG_GET_SUCCESS);
    }

    public List<BmsVideo> findByBmsId(Integer businessId,Sort sort){
        List<BmsVideo> bmsVideos = bmsVideoDao.findAllByBmsIdAndIsDeleteAndIsRelease(businessId,isDelete,isRelease,sort);
        return bmsVideos;
    }

    public List<BmsVideo> findByBmsId(Integer businessId,Pageable pageable){
        List<BmsVideo> bmsVideos = new LinkedList<>();
        Map<String,Object> conditionMap = new HashMap<>();
        conditionMap.put("bmsId",businessId);
        conditionMap.put("isDelete",isDelete);
        conditionMap.put("isRelease",isRelease);
        conditionMap.put("isOff",isOff);
        Page<BmsVideo> bmsVideosPage = bmsVideoDao.findAll(new SpecificationUtils(conditionMap),pageable);
        bmsVideos.addAll(bmsVideosPage.getContent());
        return bmsVideos;
    }

    public Map<String, Object> findMyVideo(String userIdentify, String latitude,
                                           String longitude, Integer pageNum, Integer pageSize,String headUserId) {
        //查询用户发布的视频
        Integer userId = Integer.parseInt(userIdentify);
        List<BmsUserVideo> bmsUserVideos = bmsUserVideoService.getByUserId(userId);
        Set<Integer> videoIds = new HashSet<>();
        for(BmsUserVideo bmsUserVideo : bmsUserVideos){
            videoIds.add(bmsUserVideo.getBmsVideoId());
        }
        List<BmsVideo> bmsVideos = new LinkedList<>();
        Long totalVideoNum = 0L;
        if(videoIds.size() > 0) {
            Set<Integer> fromOrigins = new HashSet<>();
            fromOrigins.add(Constants.USER_CLIENT);
            fromOrigins.add(Constants.ADMIN_CLIENT);
            Pageable pageable = BmsCommonService.getPageable(pageNum, pageSize, Sort.Direction.DESC, "newTime");
            Page<BmsVideo> bmsVideosPage = bmsVideoDao.findAll(new Specification<BmsVideo>() {
                @Override
                public Predicate toPredicate(Root<BmsVideo> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                    Map<String, Object> searchMap = new HashMap<String, Object>() {{
                        put("isDelete", Constants.COMMON_FLAG_FALSE);
                        put("ids", videoIds);
                        put("fromOrigins", fromOrigins);
                    }};
                    criteriaQuery.where(structureSqlBuild(root, criteriaBuilder, searchMap));
                    return null;
                }
            }, pageable);
            bmsVideos.addAll(bmsVideosPage.getContent());
            totalVideoNum = bmsVideosPage.getTotalElements();
        }
        //尝试获取请求头是否有用户登录
        getListPostForVideoList(bmsVideos,headUserId);
        calculatedDistance(bmsVideos,latitude,longitude);
        Map<String,Object> userData = new HashMap<>();
        userData.put("myVideoNum",totalVideoNum);
        return ResultMapHelper.success(bmsVideos,userData,"查询成功");
    }

    @Transactional
    public Map<String,Object> releaseVideo(ParamsMap paramsMap){
        //获取参数
        String userIdentify = paramsMap.get("userIdentify").toString();
        String videoFileId = paramsMap.get("video_file_id").toString();
        String videoSnapshot = paramsMap.getString("video_snapshot");
        String videoFileUrl = paramsMap.getString("video_file_url");
        //背景音乐
        String backMusic = paramsMap.getString("back_music");
        //店铺id
        Integer businessId = paramsMap.getInteger("business_id");
        //店铺名称
        String businessName = paramsMap.getString("business_name");
        //城市
        String addr = paramsMap.getString("addr");
        //地址
        String addrDetail = paramsMap.getString("addr_detail");
        //纬度
        String latitude = paramsMap.getString("latitude");
        //经度
        String longitude = paramsMap.getString("longitude");
        //用户纬度
        String userLatitude = paramsMap.getString("user_latitude");
        //用户经度
        String userLongitude = paramsMap.getString("user_longitude");
        //店铺标签
        Integer label = paramsMap.getInteger("labels");
        //视频描述
        String videoDescription = paramsMap.getString("videoDescribe");
        //音频id
        String musicId = paramsMap.getString("musicId");
        //判断是否有该商户
        Date nowTime = new Date();
        BmsBusiness business;
        if(businessId == null) {
            businessName = businessName.replaceAll(" ","");
            if(StringUtils.isBlank(businessName)){
                return ResultMapHelper.result(ResultCode.CODE_ERROR_100,"店铺名称不能为空");
            }
            /*List<BmsBusiness> businessList = bmsBusinessService.getBaseDao().findByVendorNameAndIsDeleteAndIsUnload(businessName,Constants.COMMON_FLAG_FALSE_INT,
                    Constants.COMMON_FLAG_FALSE_INT);
            if(businessList.size() > 0){
                return ResultMapHelper.failure("已存在相同名字的商家！");
            }*/
            business = new BmsBusiness();
            business.setVendorName(businessName);
            if(addr != null) {
                String[] location = addr.split("_");
                try {
                    business.setAddrProvince(location[0]);
                    business.setAddrCity(location[1]);
                    business.setAddrDistrict(location[2]);
                } catch (Exception e) {
                    log.error(e.getMessage(),e);
                }
            }
            business.setAddrDetails(addrDetail);
            business.setLatitude(latitude);
            business.setLongitude(longitude);
            bmsBusinessService.getBaseDao().save(business);
            //设置标签
            if(label != null){
                Set labelIds = new HashSet();
                labelIds.add(label);
                List<BmsBusinessLabel> bmsBusinessLabels = bmsBusinessLabelService.getBaseDao().findByIdInAndIsDelete(labelIds,Integer.parseInt(Constants.COMMON_FLAG_FALSE));
                if(bmsBusinessLabels != null && bmsBusinessLabels.size() > 0){
                    BmsBusinessLabel bmsBusinessLabel = bmsBusinessLabels.get(0);
                    Integer typeId = bmsBusinessLabel.getTypeId();
                    Optional<BmsBusinessType> bmsBusinessTypeOptional = bmsBusinessTypeService.getBaseDao().findById(typeId);
                    if(bmsBusinessTypeOptional.isPresent()){
                        BmsBusinessType bmsBusinessType = bmsBusinessTypeOptional.get();
                        business.setTags(bmsBusinessType.getTypeName());
                        bmsBusinessTypeRelationService.addBusinessRelation(business.getId(),bmsBusinessType.getId());
                    }
                    business.setLabel(bmsBusinessLabel.getLabelName());
                }
            }
            business.setIsDelete(Integer.parseInt(Constants.COMMON_FLAG_FALSE));
            business.setDkTimes(Integer.parseInt(Constants.COMMON_FLAG_FALSE));
            business.setIsAuth(Integer.parseInt(Constants.COMMON_FLAG_FALSE));
            business.setIsUnload(Integer.parseInt(Constants.COMMON_FLAG_FALSE));
            business.setNewTime(nowTime);
            bmsBusinessService.getBaseDao().save(business);
        }else {
            Optional<BmsBusiness> businessOp = bmsBusinessService.getBaseDao().findById(businessId);
            if(!businessOp.isPresent()){
                return ResultMapHelper.failure("错误,该商铺不存在");
            }
            business = businessOp.get();
        }
        //插入视频
        BmsVideoInsertDto bmsVideo = new BmsVideoInsertDto();
        bmsVideo.setVendorName(business.getVendorName());
        bmsVideo.setTags(business.getTags());
        bmsVideo.setAddrProvince(business.getAddrProvince());
        bmsVideo.setAddrCity(business.getAddrCity());
        bmsVideo.setAddrDistrict(business.getAddrDistrict());
        bmsVideo.setAddrDetails(business.getAddrDetails());
        bmsVideo.setLabel(business.getLabel());
        bmsVideo.setCloudFileId(videoFileId);
        bmsVideo.setCloudFileUrl(videoFileUrl);
        bmsVideo.setCloudFileSnapshot10Url(videoSnapshot);
        bmsVideo.setBmsId(business.getId());
        bmsVideo.setLatitude(business.getLatitude());
        bmsVideo.setLongitude(business.getLongitude());
        bmsVideo.setVideoNo(VideoUtils.getVideoNo(Constants.USER_CLIENT,bmsVideo.getTags()));
        bmsVideo.setVideoDescribe(videoDescription);
        //添加发送人信息
        BmsUser bmsUser = TokenManager.getUser(Integer.parseInt(userIdentify));
        if(bmsUser != null){
            bmsVideo.setLoginName(bmsUser.getLoginName());
        }
        bmsVideo.setFromOrigin(Constants.USER_CLIENT);
        bmsVideo.setOriginRole(Constants.USER_CLIENT);
        bmsVideoInsertDao.save(bmsVideo);
        //添加发布人信息
        BmsUserVideo bmsUserVideo = new BmsUserVideo();
        bmsUserVideo.setUserId(Integer.parseInt(userIdentify));
        bmsUserVideo.setBmsVideoId(bmsVideo.getId());
        bmsUserVideoService.save(bmsUserVideo);
        //添加到消息表
        //addReleaseVideoToBmsDxNews(bmsUser,bmsVideo);
        //视频处理
        BmsVideo bv = new BmsVideo();
        BeanUtils.copyProperties(bmsVideo,bv);
        List<BmsVideo> bmsVideos = new ArrayList<>();
        bmsVideos.add(bv);
        Set videoIds = getVideoIds(bmsVideos);
        findVideoBussess(bmsVideos);
        calculatedDistance(bmsVideos, userLatitude, userLongitude);
        setSendMes(bmsVideos,videoIds);
        Map<String,Object> resultMap = new HashMap<>();
        resultMap.put("video",bmsVideos.get(0));
        //加入消息表逻辑
        Map<String,Object> userDataMap = new HashMap<>();
        userDataMap.put("musicId",musicId);
        postHandlerVideoNew(bv,bmsUserVideo,Constants.USER_CLIENT,userDataMap);
        //为该视频发起审核
        if(BmsCommonService.checkRunProfile(BmsCommonService.RUN_PRO)){
            TCCloudUtils.videoReview(bmsVideo.getCloudFileId());
        }
        return ResultMapHelper.success(resultMap,"视频发布成功");
    }

    public void releaseVideoInit(BmsVideo bmsVideo){
        bmsVideo.setIsDelete(Integer.parseInt(Constants.COMMON_FLAG_FALSE));
        bmsVideo.setIsRelease(Integer.parseInt(Constants.COMMON_FLAG_FALSE));
        bmsVideo.setIsOff(Integer.parseInt(Constants.COMMON_FLAG_FALSE));
        bmsVideo.setIsTop(Integer.parseInt(Constants.COMMON_FLAG_FALSE));
        bmsVideo.setRecommend(defaultRecommend);
        bmsVideo.setPlayNum(Constants.COMMON_FLAG_FALSE_INT);
        bmsVideo.setCommentNum(Constants.COMMON_FLAG_FALSE_INT);
        bmsVideo.setLikeTimes(Constants.COMMON_FLAG_FALSE_INT);
        bmsVideo.setCommentNum(Constants.COMMON_FLAG_FALSE_INT);
        bmsVideo.setIsCheck(Integer.parseInt(Constants.COMMON_FLAG_FALSE));
        bmsVideo.setTranspondNum(Constants.COMMON_FLAG_FALSE_INT);
    }

    private void postHandlerVideoNew(BmsVideo bmsVideo, BmsUserVideo bmsUserVideo,
                                     Integer releaseType,Map<String,Object> userDataMap) {
        applicationContext.publishEvent(new VideoEvent("videoRelease",
                bmsVideo,bmsUserVideo,releaseType,userDataMap));
    }


    public void addReleaseVideoToBmsDxNews(BmsUser bmsUser, BmsVideo bmsVideo){
        BmsDxNews bmsDxNews = new BmsDxNews();
        //先查询视频商家的认领者
        Integer businessId = bmsVideo.getBmsId();
        BmsUserBusinessAuth bmsUserBusinessAuth = bmsUserBusinessAuthService.findByBusinessIdNotReject(businessId);
        if(bmsUserBusinessAuth == null){
            return;
        }
        bmsDxNews.setBmsUserId(bmsUserBusinessAuth.getBmsUserId());
        bmsDxNews.setBmsBusinessId(businessId);
        bmsDxNews.setOpUserId(bmsUser.getId());
        bmsDxNews.setBmsVideoId(bmsVideo.getId());
        bmsDxNews.setParentType(BmsDxNewsService.PARENTTYPT_INT);
        bmsDxNews.setChildType(BmsDxNewsService.PARENTTYPT_INT_RELEASE_VIDEO);
        bmsDxNews.setTitile(bmsUser.getLoginName());
        bmsDxNews.setVideoImg(bmsVideo.getCloudFileSnapshot10Url());
        bmsDxNews.setVideoName(bmsVideo.getVendorName());
        bmsDxNews.setNewTime(new Date());
        bmsDxNews.setUpdateTime(bmsDxNews.getNewTime());
        //bmsDxNews.setFromOrigin(Constants.BUSINESS_CLIENT);
        bmsDxNewsService.save(bmsDxNews);
    }


    public BmsVideo checkVideoExist(Integer videoId) {
        Optional<BmsVideo> bmsVideoOptional = bmsVideoDao.findById(videoId);
        if(bmsVideoOptional.isPresent()){
            BmsVideo bmsVideo = bmsVideoOptional.get();
            if(bmsVideo.getIsDelete() != Constants.COMMON_FLAG_TRUE_INT){
                return bmsVideo;
            }
        }
        return null;
    }

    @Transactional
    public Map<String, Object> delVideo(Integer userId, Integer videoId) {
        BmsVideo bmsVideo = checkVideoExist(videoId);
        if(bmsVideo == null){
            return ResultMapHelper.result(ResultCode.CODE_VIDEO_NO_EXIST,"该视频不存在");
        }
        BmsUserVideo bmsUserVideo = bmsUserVideoService.getByVideoId(videoId);
        if(bmsUserVideo == null){
            return ResultMapHelper.failure(ResultMsg.ADMIN_ERROR);
        }
        if(bmsUserVideo.getUserId().intValue() != userId.intValue()){
            return ResultMapHelper.result(ResultCode.CODE_VIDEO_NO_BELONG_TO_USER,"视频不属于该用户");
        }
        bmsVideo.setIsDelete(Constants.COMMON_FLAG_TRUE_INT);
        bmsVideoDao.save(bmsVideo);
        //删除用户发送记录表
        //bmsUserVideoService.delete(bmsUserVideo);
        //删除该视频的点赞记录
        //删除该视频的评论记录
        //删除该视频的消息记录
        //删除该视频的
        return ResultMapHelper.success(bmsVideo,ResultMsg.HAND_SUCCESS);
    }

    public Integer countBusinessReleaseNum(Integer businessId){
        return bmsVideoDao.countBusinessReleaseNum(businessId);
    }

    public Map<String, Object> getNearVideo(BmsVideoReDto bmsVideoReDto) {
        final Map<String,String> distanctMap = new HashMap<>();
        distanctMap.put("3","0-3");
        distanctMap.put("5","3-5");
        distanctMap.put("10","5-10");
        distanctMap.put("15","10-15");
        distanctMap.put("20","15-20");

        String[] km = new String[]{"0-3","3-5","5-10","10-15","15-20"};
        if(StringUtils.isNotBlank(bmsVideoReDto.getKm()) && distanctMap.containsKey(bmsVideoReDto.getKm())){
            km = new String[]{distanctMap.get(bmsVideoReDto.getKm())};
        }
        Set<Integer> videoIds = findWithinKilometersDistinctVideoIds(bmsVideoReDto.getLatitude(),bmsVideoReDto.getLongitude(),
                bmsVideoReDto.getAddrCity(),bmsVideoReDto.getAddrDistrict(),km);
        List<BmsVideo> bmsVideos = new ArrayList<>();
        if(videoIds.size() > 0){
            Map<String,Object> conditionMap = new HashMap<>();
            conditionMap.put("id_IN",videoIds);
            conditionMap.put("isDelete", Constants.COMMON_FLAG_FALSE_INT);
            conditionMap.put("isRelease", Constants.COMMON_FLAG_FALSE_INT);
            conditionMap.put("isOff", Constants.COMMON_FLAG_FALSE_INT);
            Pageable pageable = BmsCommonService.getPageable(bmsVideoReDto.getPageNum(),bmsVideoReDto.getPageSize());
            bmsVideos.addAll(bmsVideoDao.findAll(new SpecificationUtils(conditionMap),pageable).getContent());
            getListPostHand(bmsVideos,bmsVideoReDto.getLatitude(),bmsVideoReDto.getLongitude(),bmsVideoReDto.getUserId());
        }
        return ResultMapHelper.success(bmsVideos,ResultMsg.MSG_GET_SUCCESS);
    }

    public Map<Integer, BmsVideo> findByIdIn(Set<Integer> videoIds) {
        Map<Integer,BmsVideo> bmsVideoMap = new HashMap<>();
        if(videoIds.size() > 0){
            List<BmsVideo> bmsVideos = bmsVideoDao.findByIdIn(videoIds);
            if(bmsVideos.size() > 0){
                for(BmsVideo bmsVideo : bmsVideos){
                    bmsVideoMap.put(bmsVideo.getId(),bmsVideo);
                }
            }
        }
        return bmsVideoMap;
    }

    /**
     * @Description 获取必看视频
     * @Author: cfx
     * @Date: 2019/8/24
     */
    public Map<String, Object> mustSeeVideo(BmsVideoReDto bmsVideoReDto) {
        List<BmsVideo> bmsVideos = new ArrayList<>();
        Map<String,Object> conditionMap = new HashMap<>();
        conditionMap.put("isDelete", Constants.COMMON_FLAG_FALSE_INT);
        conditionMap.put("isRelease", Constants.COMMON_FLAG_FALSE_INT);
        conditionMap.put("isOff", Constants.COMMON_FLAG_FALSE_INT);
        conditionMap.put("recommend","A");
        if(isDebug == Constants.COMMON_FLAG_FALSE_INT){
            conditionMap.put("videoDescribe_NN",Constants.COMMON_FLAG_FALSE_INT);
            if(StringUtils.isNotBlank(bmsVideoReDto.getUserId())){
                String redisKey = Constants.REDIS_KEY_SELF_MUST_VIDEO_USER + bmsVideoReDto.getUserId();
                if (redisTemplate.hasKey(redisKey)) {
                    long size = redisTemplate.opsForList().size(redisKey);
                    List<BmsVideo> bmsVideoList = redisTemplate.opsForList().range(redisKey, 0, size);
                    if(bmsVideoList.size() > 0) {
                        if (bmsVideoList.size() < bmsVideoReDto.getPageSize()) {
                            bmsVideoReDto.setPageSize(bmsVideoList.size());
                        }
                        for (int ii = 0; ii < bmsVideoReDto.getPageSize(); ii++) {
                            int random = (int) (Math.random() * bmsVideoList.size());
                            bmsVideos.add(bmsVideoList.get(random));
                            bmsVideoList.remove(bmsVideoList.get(random));
                        }
                        long exipreTime = redisTemplate.getExpire(redisKey);
                        redisTemplate.delete(redisKey);
                        if(bmsVideoList.size() > 0){
                            redisTemplate.opsForList().leftPushAll(redisKey, bmsVideoList);
                            redisTemplate.expire(redisKey,exipreTime,TimeUnit.SECONDS);
                        }
                    }
                } else {
                    List<BmsVideo> bmsVideoList = bmsVideoDao.findAll(new SpecificationUtils(conditionMap));
                    if(bmsVideoList.size() > 0) {
                        if (bmsVideoList.size() < bmsVideoReDto.getPageSize()) {
                            bmsVideoReDto.setPageSize(bmsVideoList.size());
                        }
                        for (int ii = 0; ii < bmsVideoReDto.getPageSize(); ii++) {
                            int random = (int) (Math.random() * bmsVideoList.size());
                            bmsVideos.add(bmsVideoList.get(random));
                            bmsVideoList.remove(bmsVideoList.get(random));
                        }
                        if(bmsVideoList.size() > 0){
                            redisTemplate.opsForList().leftPushAll(redisKey, bmsVideoList);
                            redisTemplate.expire(redisKey,12,TimeUnit.HOURS);
                        }
                    }
                }
            }else{
                List<BmsVideo> bmsVideoList = bmsVideoDao.findAll(new SpecificationUtils(conditionMap));
                if(bmsVideoList.size() > 0) {
                    if (bmsVideoList.size() < bmsVideoReDto.getPageSize()) {
                        bmsVideoReDto.setPageSize(bmsVideoList.size());
                    }
                    for (int ii = 0; ii < bmsVideoReDto.getPageSize(); ii++) {
                        int random = (int) (Math.random() * bmsVideoList.size());
                        bmsVideos.add(bmsVideoList.get(random));
                        bmsVideoList.remove(bmsVideoList.get(random));
                    }
                }
            }
        }else {
            Integer pageSize = bmsVideoReDto.getPageSize();
            if(pageSize == null){
                return ResultMapHelper.result(ResultCode.CODE_ERROR_03,ResultMsg.CODE_ERROR_03);
            }
            try {
                Set<Integer> videoIds = new HashSet<>();
                for(int ii=0;ii<pageSize;ii++){
                    Integer id = (Integer) redisTemplate.opsForList().leftPop(Constants.REDIS_KEY_MUST_SEE_VIDEO);
                    videoIds.add(id);
                    redisTemplate.opsForList().rightPush(Constants.REDIS_KEY_MUST_SEE_VIDEO,id);
                }
                if(videoIds.size() > 0) {
                    conditionMap.put("id_IN",videoIds);
                }
            }catch (Exception e){
                conditionMap.put("recommend", ALevel);
            }
            bmsVideos = bmsVideoDao.findAll(new SpecificationUtils(conditionMap));
        }
        getListPostForVideoList(bmsVideos,bmsVideoReDto.getUserId());
        calculatedDistance(bmsVideos, bmsVideoReDto.getLatitude(), bmsVideoReDto.getLongitude());
        setIsOpenCouponAndGroupBuy(bmsVideos);
        return ResultMapHelper.success(bmsVideos,ResultMsg.MSG_GET_SUCCESS);
    }

    public void setIsOpenCouponAndGroupBuy(List<BmsVideo> bmsVideos) {
        //设置是否开通优惠买单和团购券
        //查询是否开通优惠买单
        Set<Integer> businessIds = new HashSet<>();
        if(bmsVideos != null && bmsVideos.size() >0){
            for(BmsVideo bmsVideo : bmsVideos) {
                businessIds.add(bmsVideo.getBmsId());
            }
            Map<Integer,BmsBusiness> bmsBusinessMap = bmsBusinessService.findBusinessByIds(businessIds);
            Map<Integer,Integer> bmsDxOpenMap = bmsDxCouponService.checkIsOpenCoupon(businessIds);
            Map<Integer,Integer> bmsGroupBuyOpenMap = bmsDxGroupBuyService.checkIsOpenGroupBuy(businessIds);
            for(BmsVideo bmsVideo : bmsVideos){
                BmsBusiness business = bmsVideo.getBmsBusiness();
                if(business == null){
                    if(bmsBusinessMap.containsKey(bmsVideo.getBmsId())){
                        business = bmsBusinessMap.get(bmsVideo.getBmsId());
                    }
                }
                if(business != null) {
                    if (bmsDxOpenMap.containsKey(business.getId())) {
                        business.setIsOpenCoupon(Constants.COMMON_FLAG_TRUE_INT);
                    }
                    if (bmsGroupBuyOpenMap.containsKey(business.getId())) {
                        business.setIsOpenGroupBuy(Constants.COMMON_FLAG_TRUE_INT);
                    }
                    BmsBusiness bmsBusiness = new BmsBusiness();
                    BeanUtils.copyProperties(business,bmsBusiness);
                    bmsBusiness.setBmsVideos(null);
                    bmsVideo.setBmsBusiness(bmsBusiness);
                }
            }
        }
    }

    public Set<Integer> findVideoByNameAndDesc(String searchText) {
        Set<Integer> videoIds = new HashSet<>();
        List<Map<String,Object>> videoIdMap = bmsVideoDao.getVideoByNameAndDesc(searchText);
        if(videoIdMap != null && videoIdMap.size() > 0){
            for(Map<String,Object> videoId : videoIdMap){
                videoIds.add(Integer.parseInt(videoId.get("id").toString()));
            }
        }
        return videoIds;
    }

    public byte[] getDecryptionData(String edk) {
        String redisKey = Constants.REDIS_KEY_VIDEO_PLAY;
        String dk = null;
        if(redisTemplate.opsForHash().hasKey(redisKey,edk)){
            dk = redisTemplate.opsForHash().get(redisKey,edk).toString();
        }else {
            TreeMap<String, Object> config = new TreeMap<String, Object>();
            config.put("SecretId", AppConfig.getProperty("cloud.secret.id"));
            config.put("SecretKey", AppConfig.getProperty("cloud.secret.key"));
            config.put("RequestMethod", "GET");
            config.put("DefaultRegion", "gz");
            QcloudApiModuleCenter module = new QcloudApiModuleCenter(new Vod(),
                    config);
            TreeMap<String, Object> params = new TreeMap<String, Object>();
            params.put("edkList.0", edk);
            String result = null;
            try {
                result = module.call("DescribeDrmDataKey", params);
                JSONObject jsonObject = JSON.parseObject(result);
                if(jsonObject.containsKey("code") && jsonObject.get("code").toString().equals("0")){
                    JSONObject data = jsonObject.getJSONObject("data");
                    JSONArray jsonArray = data.getJSONArray("keyList");
                    dk = jsonArray.getJSONObject(0).get("dk").toString();
                    //存在redis里面
                    if(StringUtils.isNotBlank(dk)){
                        redisTemplate.opsForHash().put(redisKey,edk,dk);
                    }
                }
            } catch (Exception e) {
                System.out.println("error..." + e.getMessage());
            }
        }
        byte[] dkBin = Base64.getDecoder().decode(dk);
        return dkBin;
    }

    public void AdjustVideoRating(Set<Integer> businessIds) {
        Map<String,Object> conditionMap = new HashMap<>();
        if(businessIds.size() > 0) {
            conditionMap.put("bmsId_IN", businessIds);
            conditionMap.put("recommend_NEQ","E");
            List<BmsVideo> bmsVideos = bmsVideoDao.findAll(new SpecificationUtils(conditionMap));
            if(bmsVideos != null && bmsVideos.size() > 0){
                for(BmsVideo bmsVideo : bmsVideos){
                    bmsVideo.setRecommend("E");
                }
            }
            bmsVideoDao.saveAll(bmsVideos);
        }
    }
}
